<template>
	<div class="app-container app-map-container" v-loading="mapLoading">
		<!-- 地图 -->
		<div id="qq-map-container" class="qq-map-container"></div>

		<!-- 底部编辑器 -->
		<div v-show="hasInfoAdd || hasChoose" id="qq-map-tool-control"
			class="qq-map-tool-control flex justify-center align-center" @click="clickQQMapTool">
			<div v-show="hasInfoAdd" :class="['qq-map-tool-item', {'active':mapToolActiveTypeIsMarker}]"
				id="qq-map-tool-marker" v-popover:too_popover_marker data-id="qq-map-tool-marker">
				<div class="qq-map-tool-item-icon" data-id="qq-map-tool-marker"
					:style="{backgroundImage:'url('+toolIconMarker+')'}"></div>
				<div class="qq-map-tool-item-title" data-id="qq-map-tool-marker">新增项目</div>
			</div>
			<div v-show="hasChoose" :class="['qq-map-tool-item', {'active':mapToolActiveTypeIsLocate}]"
				id="qq-map-tool-locate" v-popover:too_popover_locate data-id="qq-map-tool-locate">
				<div class="qq-map-tool-item-icon" data-id="qq-map-tool-locate"
					:style="{backgroundImage:'url('+toolIconLocate+')'}"></div>
				<div class="qq-map-tool-item-title" data-id="qq-map-tool-locate">项目单选</div>
			</div>
			<div v-show="hasChoose" :class="['qq-map-tool-item', {'active':mapToolActiveTypeIsPolygon}]"
				id="qq-map-tool-polygon" v-popover:too_popover_polygon data-id="qq-map-tool-polygon">
				<div class="qq-map-tool-item-icon" data-id="qq-map-tool-polygon"
					:style="{backgroundImage:'url('+toolIconPolygon+')'}"></div>
				<div class="qq-map-tool-item-title" data-id="qq-map-tool-polygon">多边框选</div>
			</div>
			<div v-show="hasChoose" :class="['qq-map-tool-item', {'active':mapToolActiveTypeIsCircle}]"
				id="qq-map-tool-circle" v-popover:too_popover_circle data-id="qq-map-tool-circle">
				<div class="qq-map-tool-item-icon" data-id="qq-map-tool-circle"
					:style="{backgroundImage:'url('+toolIconCircle+')'}"></div>
				<div class="qq-map-tool-item-title" data-id="qq-map-tool-circle">半径框选</div>
			</div>
			<div v-show="hasChoose" :class="['qq-map-tool-item', {'active':mapToolActiveTypeIsDelete}]"
				id="qq-map-tool-delete" v-popover:too_popover_delete data-id="qq-map-tool-delete">
				<div class="qq-map-tool-item-icon" data-id="qq-map-tool-delete"
					:style="{backgroundImage:'url('+toolIconDelete+')'}"></div>
				<div class="qq-map-tool-item-title" data-id="qq-map-tool-delete">删除选框</div>
			</div>
			<div v-show="hasChoose" class="qq-map-tool-item" id="qq-map-tool-reset" v-popover:too_popover_reset
				data-id="qq-map-tool-reset">
				<div class="qq-map-tool-item-icon" data-id="qq-map-tool-reset"
					:style="{backgroundImage:'url('+toolIconReset+')'}"></div>
				<div class="qq-map-tool-item-title" data-id="qq-map-tool-reset">清除选点</div>
			</div>
		</div>
		<el-popover ref="too_popover_marker" placement="top" title="新增项目" width="370" trigger="hover">
			<div>
				<div class="text-sm">点击进入“新增项目”模式，单击地图<span class="text-orange">新增项目</span>。</div>
				<div class="margin-top padding-top-sm solid-top text-xs">
					<div>使用方法：</div>
					<div> 1、单击地图，获取经纬度并弹出新增信息框。</div>
					<div> 2、在“新增项目”模式下，不可点击标记点查看项目信息。</div>
					<div> 3、再次点击该按钮，即可退出“新增项目”模式。</div>
				</div>
			</div>
		</el-popover>
		<el-popover ref="too_popover_locate" placement="top" title="项目单选" width="370" trigger="hover">
			<div>
				<div class="text-sm">点击进入“项目单选”模式。</div>
				<div class="margin-top padding-top-sm solid-top text-xs">
					<div> 单击项目标记，弹出信息窗口，点击信息窗口内的“<span class="text-orange">加入待选</span>”即可选中。</div>
				</div>
			</div>
		</el-popover>
		<el-popover ref="too_popover_polygon" placement="top" title="多边框选" width="370" trigger="hover">
			<div>
				<div class="text-sm">点击进入“多边框选”模式，用于选出<span class="text-orange">框定区域项目</span>。</div>
				<div class="margin-top padding-top-sm solid-top text-xs">
					<div>使用方法：</div>
					<div> 1、单击和移动鼠标，画出边界。</div>
					<div> 2、双击结束绘画，会自动补全最后的边线。</div>
					<div> 3、在“多边框选”模式下，不可点击标记点查看项目信息。</div>
				</div>
			</div>
		</el-popover>
		<el-popover ref="too_popover_circle" placement="top" title="半径框选" width="370" trigger="hover">
			<div>
				<div class="text-sm">点击进入“半径框选”模式，用于选出<span class="text-orange">框定区域项目</span>。</div>
				<div class="margin-top padding-top-sm solid-top text-xs">
					<div>使用方法：</div>
					<div> 1、单击圆心，移动鼠标放大。</div>
					<div> 2、再次点击结束绘画。</div>
					<div> 3、在“半径框选”模式下，不可点击标记点查看项目信息。</div>
				</div>
			</div>
		</el-popover>
		<el-popover ref="too_popover_delete" placement="top" title="删除选框" width="370" trigger="hover">
			<div>
				<div class="text-sm">点击进入“删除选框”模式。</div>
				<div class="margin-top padding-top-sm solid-top text-xs">
					<div>使用方法：</div>
					<div> 1、单选：鼠标左键点击选框。</div>
					<div> 2、多选：按下ctrl键后点击多个选框。</div>
					<div> 3、选中图形后按下delete键，即可删除选框。</div>
					<div> 4、在“删除选框”模式下，不可点击标记点查看项目信息。</div>
				</div>
			</div>
		</el-popover>
		<el-popover ref="too_popover_reset" placement="top" title="清除选点" width="300" trigger="hover">
			<div>
				<div class="text-sm">清除<span class="text-orange">选框和选中数据</span>。</div>
			</div>
		</el-popover>

		<!-- 顶部 -->
		<div v-show="hasSearch || hasNameSwitch || hasDonutSwitch || hasDateRange || title"
			class="address-search flex flex-no-wrap justify-start align-start" :style="{'width':'inherit', 'marginLeft':!chooseBuildingOnly?'0':'400px'}">
			<div class="flex-none padding-tb-sm padding-lr bg-white text-xxl text-bold text-center solids radius shadow"
				v-show="title" style="width: 240px;margin:5px 30px 10px;">{{title}}</div>

			<div v-show="hasSearch || hasNameSwitch || hasDonutSwitch || hasDateRange"
				class="flex flex-wrap justify-start align-center flex-auto margin-left-sm" style="margin-right: 160px;width:calc(100% - 470px)">
				<el-date-picker :editable="false" :clearable="false" class="margin-xs" v-show="hasDateRange"
					size="small" v-model="dateRange" type="daterange" range-separator="至" start-placeholder="开始日期"
					end-placeholder="结束日期" format="yyyy年MM月dd日" value-format="yyyy-MM-dd HH:mm:ss"
					:default-time="['00:00:00', '23:59:59']" style="width:350px" @change="changeDateRange">
				</el-date-picker>
				<el-input class="address-input margin-xs" v-show="hasSearch && !useNewAddressSearch" v-model="searchForm.address" clearable
					placeholder="请输入地址" size="small">
					<el-cascader slot="prepend" v-model="searchForm.pca" filterable placeholder="请选择省市"
						:options="pcAll" size="small" class="address-cascader" @change="changeCity"></el-cascader>
					<el-button slot="append" icon="el-icon-search" @click.native="searchAddress" size="small">
					</el-button>
				</el-input>
				<div class="bg-white margin-xs top-tool top-tool-switch">
					<div class="flex justify-start align-center flex-no-wrap padding-xs">
						<el-switch v-show="hasNameSwitch" v-model="showLabel" active-text="名称" active-value="1"
							inactive-value="0" @change="changeShowLabel">
						</el-switch>
						<el-switch v-show="hasDonutSwitch" v-model="showDonut" active-text="饼图" active-value="1"
							inactive-value="0" @change="changeShowDonut" class="margin-left-sm">
						</el-switch>
					</div>
				</div>
				<!-- <div class="bg-white margin-xs solid radius" v-show="!showInstalledNum && hasPointTypeSwitch && point_types.length>1" :key="point.id" v-for="point in point_types">
					<el-switch v-model="point.show" :active-text="point.name" 
					:active-value="true" :inactive-value="false" @change="(val) => changePointTypeShow(point.id, val)" 
					class="padding-tb margin-lr-sm">
					</el-switch>
				</div> -->
				<div class="bg-white margin-xs top-tool top-tool-select"
					v-show="!showInstalledNum && hasPointTypeSwitch && point_types.length>1">
					<div class="flex justify-start align-center flex-no-wrap padding-xs">
						<div class="padding-right-xs text-sm">点位类型</div>
						<el-select v-model="point_types_show_selected" collapse-tags filterable multiple
							placeholder="请选择点位类型" :size="!!useNewAddressSearch?'small':'mini'" @change="changePointTypeShowSelect">
							<el-option v-for="point in point_types" :key="point.id" :label="point.name"
								:value="point.id" />
						</el-select>
					</div>
				</div>
				<div class="bg-white margin-xs top-tool top-tool-select" v-show="hasAreaSelect && areaAll.length>0">
					<div class="flex justify-start align-center flex-no-wrap padding-xs">
						<div class="padding-right-xs text-sm">行政区划</div>
						<el-select v-model="area_selected" collapse-tags filterable multiple placeholder="请选择区"
							size="mini" @change="changeAreaSelect">
							<el-option v-for="item in areaAll" :key="item.value" :label="item.label"
								:value="item.value" />
						</el-select>
					</div>
				</div>
				<div class="bg-white margin-xs top-tool top-tool-select"
					v-show="hasTradeAreaSelect && tradeAreaAll.length>0 && !useNewAddressSearch">
					<div class="flex justify-start align-center flex-no-wrap padding-xs">
						<div class="padding-right-xs text-sm">商圈</div>
						<el-select v-model="trade_area_selected" collapse-tags filterable multiple placeholder="请选择商圈"
							size="mini" @change="changeTradeAreaSelect" value-key="id">
							<el-option v-for="item in tradeAreaAll" :key="item.id" :label="item.title" :value="item">
								<div class="flex justify-between align-center flex-no-wrap">
									<div class="text-df">{{item.title}}</div>
									<div class="text-xs text-gray margin-left">{{item.address}}</div>
								</div>
							</el-option>
						</el-select>
						<div class="padding-left-sm padding-right-xs text-sm">辐射半径</div>
						<el-input-number v-model="trade_area_radius" :controls="false" size="mini" :min="1"
							step-strictly style="width:80px" @change="changeTradeRadius" />
						<div class="padding-left-xs text-xs">米</div>
					</div>
				</div>
				
				
				<div class="bg-white margin-xs top-tool top-tool-select"
					v-show="hasSearch && !!useNewAddressSearch">
					<div class="flex justify-start align-center flex-no-wrap padding-xs">
						<el-input class="address-input margin-lr-xs" v-show="hasSearch && !!useNewAddressSearch" v-model="searchForm.address" clearable
							placeholder="请输入地址" size="small">
							<el-cascader slot="prepend" v-model="searchForm.pca" filterable placeholder="请选择省市"
								:options="pcAll" size="small" class="address-cascader" @change="changeCity"></el-cascader>
							<!-- <el-button slot="append" icon="el-icon-search" @click.native="searchAddressNew" size="small" /> -->
						</el-input>
						<div class="padding-left-sm padding-right-xs text-sm">辐射半径</div>
						<el-input-number v-model="address_radius" :controls="false" size="small" :min="1"
							step-strictly style="width:80px"/>
						<div class="padding-left-xs text-xs">米</div>
						<el-button class="margin-left-sm" type="primary" plain round icon="el-icon-search" size="mini" @click.native="searchAddressNew">确定</el-button>
					</div>
				</div>
				<!-- <div class="bg-white margin-xs top-tool top-tool-select"
					v-show="hasTradeAreaSelect && tradeAreaAll.length>0 && !!useNewAddressSearch">
					<div class="flex justify-start align-center flex-no-wrap padding-xs">
						<div class="padding-right-xs text-sm">商圈</div>
						<el-select v-model="trade_area_selected" collapse-tags filterable multiple placeholder="请选择商圈"
							size="small" value-key="id">
							<el-option v-for="item in tradeAreaAll" :key="item.id" :label="item.title" :value="item">
								<div class="flex justify-between align-center flex-no-wrap">
									<div class="text-df">{{item.title}}</div>
									<div class="text-xs text-gray margin-left">{{item.address}}</div>
								</div>
							</el-option>
						</el-select>
						<div class="padding-left-sm padding-right-xs text-sm">辐射半径</div>
						<el-input-number v-model="trade_area_radius" :controls="false" size="small" :min="1"
							step-strictly style="width:80px" />
						<div class="padding-left-xs text-xs">米</div>
						<el-button class="margin-left-sm" type="primary" plain round icon="el-icon-search" size="mini" @click.native="searchTradeAreaSelect">确定</el-button>
					</div>
				</div> -->
			</div>
		</div>

		<!-- 地址搜索结果弹框 -->
		<el-dialog title="相似地址" :visible.sync="searchDialogVisible" width="60%" center @close="closeSearchDialog">
			<div class="flex-direction justify-start align-center search-dialog">
				<div v-for="item in searchAddresses" :key="item.id"
					class="search-ad-item flex justify-between align-center padding-xs">
					<div>
						<div class="text-black text-bold">
							{{item.title}}
						</div>
						<div class="text-gray text-xs margin-top-xs">
							{{item.address}}
						</div>
					</div>
					<div class="flex justify-end align-center">
						<el-button type="text" class="padding-0 text-xs"
							@click.stop="chooseSearchADItemToMapCenter(item)">
							定位</el-button>
						<el-button v-show="hasInfoAdd" type="text" class="padding-0 text-xs"
							@click.stop="chooseSearchADItemToAddPoint(item)">
							新增点位</el-button>
						<el-button v-show="hasChoose" type="text" class="padding-0 text-xs"
							@click.stop="chooseSearchADItemToAddCircle(item)">
							辐射选点</el-button>
					</div>
				</div>
			</div>
		</el-dialog>

		<!-- 辐射半径弹框 -->
		<el-dialog :close-on-click-modal="false" title="辐射半径" center :visible.sync="dialogRadius" width="40%"
			@close="dialogCUClose('radiusForm')">
			<el-form ref="radiusForm" v-loading="dialogRadiusLoading" :rules="radiusRules" :model="radiusForm"
				label-width="100px" center>
				<el-row class="margin-top-sm">
					<el-col :span="24">
						<el-form-item label="辐射半径" prop="radius">
							<el-col :span="24">
								<el-input clearable v-model.trim="radiusForm.radius" type="number"
									placeholder="请输入辐射半径">
									<template slot="append">米</template>
								</el-input>
							</el-col>
						</el-form-item>
					</el-col>
				</el-row>
			</el-form>
			<span slot="footer" class="dialog-footer">
				<el-button @click.native="dialogRadius=false">取 消</el-button>
				<el-button type="primary" @click.native="confirmSearchADItemToAddCircle()">确 定</el-button>
			</span>
		</el-dialog>

		<div v-show="mapToolCircleRadiusDisShow" :style="mapToolCircleRadiusDisComputeStyle"
			class="padding-xs circleRadiusDisBox">
			{{mapToolCircleRadiusDis}}米
		</div>

		<!-- 已选中项目悬浮框 -->
		<transition name="choosed-building-area">
			<div class="choosed-building-area bg-white padding-sm" v-show="!hideChoosedBox" :style="{'width':!chooseBuildingOnly?'300px':'400px'}">
				<div class="text-center padding-xs choosed-box">
					<div class="text-df text-bold">已选中项目 ({{(choosedBuildingAreas||[]).length}})</div>
					<div class="choosed-export">
						<el-button v-if="hasChoosedExport" type="text" class="padding-0 text-xxs"
							@click.native="exportChoosedList">导出
						</el-button>
					</div>
				</div>
				<div
					class="choosed-building-areas-list flex-direction justify-start align-end text-xs padding-tb-xs margin-top-xs dashed-top">
					<div class="padding-xs text-left text-xs" v-show="!!showCounts">
						总计：<span class="text-blue margin-right-sm">{{choosedBuildingAreasSum.sum.can}}</span>
					</div>
					<div class="padding-xs text-left text-xs margin-left-sm" v-show="!!showCounts">
						<div class="text-gray" v-for="i in Object.keys(choosedBuildingAreasSum.pointTypes.can)">
							{{point_types_map[i].name}}(<span
								class="text-blue">{{choosedBuildingAreasSum.pointTypes.can[i]}}</span>)
							<br v-if="((choosedBuildingAreasSum.pointTypes.device_size || {})[i] || []).length>0" />
							<div class="margin-left-sm text-xxs" v-if="((choosedBuildingAreasSum.pointTypes.device_size || {})[i] || []).length>0"
								v-for="(ds, idx) in ((choosedBuildingAreasSum.pointTypes.device_size || {})[i] || [])">
								({{idx+1}}){{ds.size}}(<span class="text-green">{{ds.count}}</span>) </div>
						</div>
					</div>
					<div v-for="(item,index) in (choosedBuildingAreas || [])" :key="item.id"
						class="padding-xs text-center flex justify-between align-center choosed-building-areas-list-item solid-top"
						style="line-height: 1.3;">
						<div class="text-left choosed-building-areas-list-item-name" v-show="!chooseBuildingOnly">
							<span class="text-bold">{{index+1}}、</span>
							<span class="text-bold">{{item.name}}</span><br />
							<span class="padding-left-lg" v-show="!!showCounts">
								<span v-if="!showInstalledNum && !showUninstalledNum"> (<span
										class="text-red text-xxs">{{countPointTypeName[0]}}:{{building_sum[item.id].used}}</span>/<span
										class="text-orange text-xxs">{{countPointTypeName[1]}}:{{building_sum[item.id].locked}}</span>/<span
										class="text-blue text-xxs">{{countPointTypeName[2]}}:{{building_sum[item.id].can}}</span>)</span>
								<span v-else-if="showInstalledNum"> (<span
										class="text-blue text-xxs">{{building_sum[item.id].can}}</span>)</span>
								<span v-else-if="showUninstalledNum"> (<span
										class="text-blue text-xxs">{{building_sum[item.id].can}}</span>)</span>
							</span>
							<br v-if="!!showCounts && !showUninstalledNum && (item.device_size || []).length>0" />
							<span class="padding-left-xl" v-if="!!showCounts && !showUninstalledNum" style="display: inline-block;">
								<span v-for="s of item.device_size" v-if="(point_types_show_selected || []).indexOf(s.point_type_id)>-1">{{s.point_type}}({{s.size}})：<span
										class="text-green">{{s.count}}</span> 个<br /></span>
							</span>
						</div>
						<div class="flex-auto flex justify-start align-center flex-no-wrap" v-show="!!chooseBuildingOnly">
							<div style="width: 80px; height: 60px">
								<el-image style="width: 80px; height: 60px" :src="item.photo" fit="scale-down" v-if="!!item.photo"></el-image>
								<el-image v-else>
									<!-- <div slot="error" style="width: 80px; height: 60px;background-color: #ddd;" class="flex justify-center align-center flex-no-wrap text-bold">{{item.first_char}}</div> -->
									<div slot="error" style="width: 80px; height: 60px;background-color: #ddd;" class="flex justify-center align-center flex-no-wrap text-bold">请上传项目大门照片</div>
								</el-image>
							</div>
							<div class="margin-left-xs flex flex-direction justify-between align-start flex-no-wrap" style="height: 50px;">
								<div style="height: 15px;white-space: nowrap;overflow: hidden;text-overflow: ellipsis;max-width: 250px;">
									<span class="text-bold">{{index+1}}、</span>
									<span class="text-bold">{{item.name}}</span>
								</div>
								<div style="height: 15px;white-space: nowrap;overflow: hidden;text-overflow: ellipsis;max-width: 250px;">
									<span class="text-gray">{{(item.address || '')}}</span>
								</div>
								<div style="height: 15px;">
									<span>{{(item.check_in_at || '').substring(0,4)}}入住</span>
									 | <span>{{(item.occupancy_rate || '')}}%</span>
									 | <span>{{(item.scale || '')}}人</span>
									 | <span>￥{{(item.price || '')}}/m²</span>
								</div>
							</div>
						</div>
						<div class="flex justify-end align-center">
							<el-button v-show="hasChoose" type="text" class="padding-0 text-xxs text-red"
								@click.native="removeChoosed(item.id)">移除</el-button>
						</div>
					</div>
				</div>
				<div class="flex justify-between align-center padding-top-xs dashed-top"
					v-show="isChooseSetting && choosedBuildingAreas && choosedBuildingAreas.length > 0">
					<el-button v-show="isChooseSetting" type="text" class="padding-0 text-xs choose-operator"
						@click.native="confirmChooseSetting">确认</el-button>
				</div>
			</div>
		</transition>
		<!-- <choosed-setting ref="settingDialog" :hasCombo="!showUninstalledNum" :hasExact="!showUninstalledNum"
			:hasDateRange="!showUninstalledNum" :hasFloorLimt="hasFloorLimt" :hasOneLimt="hasOneLimt"
			:visible.sync="showSettingDialog" @on-confirm="settingDialogOnConfirm"></choosed-setting> -->
			
		<!-- 新地址搜索弹框 -->
		<AddressSearch ref="addressSearch" @choose-addresses="choosedAddresses"
			@close-choose-address="closeAddressChooseDialog" />
	</div>
</template>
<script>
	import {
		get_media_types,
		//export_building_list, // 导出项目信息
		get_map_center, // 获取地图中心位置
		ip_location, // 腾讯位置服务，ip定位
		geocoder, // 腾讯位置服务，逆地址编码
		pc_list_all, // 所有省市
		area_list, // 根据市id获取所有区
		area_search, // 获取区详情
		search_trade_area,
		search_address, //腾讯位置服务，地址搜索
		list_for_map as building_area_list, // 根据可视区域，查询项目列表
		building_area_for_point_plan_map // 根据可视区域，查询项目列表（选位方案专用）
	} from '@/api/building/building'
	import common from '@/utils/common.js';
	import pinyin from '@/utils/chinesePY.js';
	import {
		Donut
	} from './js/donut.js';
	import {
		MyLabel
	} from './js/myLabel.js';
	import {
		isArray,
		isObject,
		isTrue,
		isFunction,
		generateUUID,
		accMul,
		accAdd,
		formatDate,
		getTimeSlot,
		getAdcodeListByAdcode,
		compareArrayToGetDiffs,
		formatDateByFmt
	} from '@/utils/util.js'
	import {
		cloneDeep
	} from 'lodash'
	import {
		mapChoosedMarker,
		mapMarker,
		mapMarker11,
		mapMarker12,
		mapMarker23 as mapMarker21,
		mapMarker22,
		mapMarker33 as mapMarker31,
		mapMarker32,
		mapMarker43 as mapMarker41,
		mapMarker42,
		mapMarker93 as mapMarker91,
		mapMarker92,
		mapMarker103 as mapMarker101,
		mapMarker102,
		mapMarker113 as mapMarker111,
		mapMarker112,
		mapMarker123 as mapMarker121,
		mapMarker122,
		toolIconMarker,
		toolIconCircle,
		toolIconPolygon,
		toolIconDelete,
		toolIconReset,
		toolIconLocate
	} from './image/image.js'
	//import ChoosedSetting from '@/components/TencentMap/ChoosedSetting'
	import AddressSearch from '@/components/PointPlanSetting/addressSearch';
	export default {
		name: 'TencentMap',
		beforeRouteLeave(to, from, next) {
			if (this.mapObject.map) this.mapObject.map.destroy()
			//this.$destroy();
			next();
		},
		beforeDestroy() {
			if (this.mapObject.map) this.mapObject.map.destroy()
		},
		components: {
			//ChoosedSetting,
			AddressSearch
		},
		props: {
			title: {
				type: String,
				default: ""
			},
			hasNameSwitch: {
				type: Boolean,
				default: true
			},
			showDonutProp: {
				type: Boolean,
				default: false
			},
			hasDonutSwitch: {
				type: Boolean,
				default: false
			},
			hasInfoAdd: {
				type: Boolean,
				default: false
			},
			hasInfoEdit: {
				type: Boolean,
				default: false
			},
			hasInfoDel: {
				type: Boolean,
				default: false
			},
			hasSearch: {
				type: Boolean,
				default: false
			},
			hasChoose: {
				type: Boolean,
				default: false
			},
			isChooseSetting: {
				type: Boolean,
				default: false
			},
			hasDateRange: {
				type: Boolean,
				default: false
			},
			dateRange: {
				type: Array,
				default: () => {
					return [formatDate(new Date()) + ' 00:00:00', formatDate(new Date()) + ' 23:59:59']
				}
			},
			hasOneLimt: { // 选点配置，一层一个限制，仅限电梯媒体
				type: Boolean,
				default: false
			},
			hasFloorLimt: { // 楼层限制，仅限梯外框架（123）、宣传栏媒体（125），1：无；2：地上；3：地下
				type: Boolean,
				default: false
			},
			hasPointTypeSwitch: { // 类型开关
				type: Boolean,
				default: true
			},
			hasAreaSelect: {
				type: Boolean,
				default: false
			},
			hasTradeAreaSelect: {
				type: Boolean,
				default: false
			},

			showInstalledNum: {
				type: Boolean,
				default: false
			},
			pointTypes: {
				type: Array,
				default: () => []
			},
			showUninstalledNum: {
				type: Boolean,
				default: false
			},
			zeroShowProp: {
				type: Boolean,
				default: false
			},
			zeroShowExceptPointTypeSwitchProp: {
				type: Boolean,
				default: false
			},
			hasChoosedExport: {
				type: Boolean,
				default: false
			},
			showCounts: { // 显示点位数
				type: Boolean,
				default: true
			},
			useNewAddressSearch:{ // 使用新版地址搜索，完成选择进行辐射
				type: Boolean,
				default: false
			},
			chooseBuildingOnly:{// 仅选择项目
				type: Boolean,
				default: false
			}
		},
		data() {
			return {
				mapLoading: false,

				toolIconMarker,
				toolIconCircle,
				toolIconPolygon,
				toolIconDelete,
				toolIconReset,
				toolIconLocate,
				// 点位下拉框相关
				point_types_show: {},
				point_types_show_selected: [],
				// 项目点位数量（总已用、总锁定、总可用、对应分点位类型的合计）
				building_sum: {},
				// 地图默认缩放参数
				mapDefaultZoom: 15,
				// 所有点位的map<point_type_id, object>
				point_types_map: {},
				// 点位类型
				point_types: [],
				// 所有省市
				pcAll: [],
				// 当前选中市下的所有区
				areaAll: [],
				// 下拉框选中的区
				area_selected: [],
				// 所有商圈（注：默认根据地图中心点，拉取附近20条）
				tradeAreaAll: [],
				// 选中的商圈
				trade_area_selected: [],
				// 商圈辐射半径
				trade_area_radius: 1000,
				// 搜索表单
				searchForm: {
					pca: null,
					address: null,
				},
				// 新版搜索地址，多地址经纬度
				address_circle_locations: [],
				// 新版搜索地址，辐射半径
				address_radius: 1000,
				// 搜索结果弹框可见性
				searchDialogVisible: false,
				// 搜索结果列表
				searchAddresses: [],
				// 缩放拉取标志位
				zoomLoadingFlag: false,
				// 饼图标记点，3种大小
				donutSize: [{
						minRadius: 14,
						maxRadius: 21
					},
					{
						minRadius: 20,
						maxRadius: 28
					},
					{
						minRadius: 25,
						maxRadius: 35
					}
				],
				//dateRange: this.dateRangeProp,
				// 饼图开关，默认关闭
				showDonut: this.showDonutProp ? '1' : '0',
				// 名称开关，默认显示
				showLabel: '0',
				// 用于存储各个地图对象
				mapObject: {},
				// 已选中的项目
				choosedBuildingAreas: [],
				// 已选中的项目合计
				choosedBuildingAreasSum: {
					sum: {
						used: 0,
						locked: 0,
						can: 0
					},
					pointTypes: {
						used: {},
						locked: {},
						can: {}
					}
				},
				// 项目数据，id为key
				buildingAreas: {},
				// 点位数量说明
				countPointTypeName: ['刊', '锁', '空'],

				// 信息窗，项目信息对象
				curInfo: {},

				// 当前活跃的地图编辑器
				mapToolActiveType: this.hasChoose ? 'qq-map-tool-locate' : '',
				mapToolCircleRadiusDisShow: false,
				mapToolCircleRadiusDis: 0,
				mapToolCircleRadiusDisPoint: {
					x: 0,
					y: 0
				},
				mapToolCircleRadiusDisPosition: {
					top: 20,
					left: 20
				},
				mapToolCircleRadiusDisStyle: {
					position: 'absolute',
					top: '20px',
					left: '20px',
					zIndex: '2000'
				},
				// 当前编辑和选中的数据ids
				mapToolIds: {
					marker: [],
					polygon: [],
					circle: []
				},
				// 框选的id与选中的项目列表
				mapToolIdAndBuildings: {},
				// 左侧已选中的项目的box的可见性
				hideChoosedBox: this.hasChoose ? false : true,

				// 辐射半径编辑框loading
				dialogRadiusLoading: false,
				// 辐射半径弹框可见性
				dialogRadius: false,
				// 辐射半径
				radiusForm: {
					radius: null
				},
				// 表单校验
				radiusRules: {
					radius: [{
						required: true,
						message: '请输入辐射半径',
						trigger: 'blur'
					}]
				},
				// 搜索，辐射半径半径框选，圆心经纬度
				radiusLatLng: {
					lat: null,
					lng: null
				},

				// 选点配置弹框
				showSettingDialog: false,

				// 是否显示总数为0的点位
				zeroShow: this.zeroShowProp,
				// 与zeroShow一起使用，所有类型都开启时显示0总数点位，存在关闭类型则只显示非0总数点位
				zeroShowExceptPointTypeSwitch: this.zeroShowExceptPointTypeSwitchProp
			}
		},
		computed: {
			mapToolCircleRadiusDisComputeStyle() {
				return {
					position: 'absolute',
					top: this.mapToolCircleRadiusDisPosition.top + 'px',
					left: this.mapToolCircleRadiusDisPosition.left + 'px',
					zIndex: '2000'
				}
			},
			mapToolActiveTypeIsLocate() {
				return this.mapToolActiveType === 'qq-map-tool-locate'
			},
			mapToolActiveTypeIsMarker() {
				return this.mapToolActiveType === 'qq-map-tool-marker'
			},
			mapToolActiveTypeIsPolygon() {
				return this.mapToolActiveType === 'qq-map-tool-polygon'
			},
			mapToolActiveTypeIsCircle() {
				return this.mapToolActiveType === 'qq-map-tool-circle'
			},
			mapToolActiveTypeIsDelete() {
				return this.mapToolActiveType === 'qq-map-tool-delete'
			}
		},
		mounted() {
			const that = this
			that.getPointTypes()
			that.$nextTick(() => {
				that.initPCAndMap()
			})
		},
		methods: {
			// 新版地址搜索，选择回调
			choosedAddresses(locations){
				const that = this;
				
				const loading = common.showLoading();
				
				let lMap = new Map();
				(locations||[]).forEach(l => {
					lMap.set(l.id, l);
				})
				
				//console.log(locations);
				const newIds = (locations || []).map(d => d.id);
				const oldIds = (that.address_circle_locations || []).map(d => d.id);
				
				let compareR = compareArrayToGetDiffs(newIds, oldIds);
				//console.log(compareR);
				if ((compareR.less1 || []).length > 0 || (compareR.same || []).length > 0) {
					let ids = [...compareR.less1, ...compareR.same].filter(id => {
						const gId = id;
						if (!!that.mapToolIdAndBuildings[gId]) return true
						else return false;
					})
					that.getEditorOverlay('qq-map-tool-circle').remove(ids);
					ids.forEach(id => that.afterDelPolygonOrCircleEditor(id, 'circle'));
				}
				if ((compareR.over1 || []).length > 0 || (compareR.same || []).length > 0){
					let ids = [...compareR.over1, ...compareR.same].filter(id => {
						const gId = id;
						if (!that.mapToolIdAndBuildings[gId]) return true
						else return false;
					})
					for (let id of ids) {
						const gId = id;
						const o = lMap.get(gId);
						if(!!o) that.addCircle(o.location.lat, o.location.lng, that.address_radius, gId, o.title || '');
					}
				}
				that.address_circle_locations = locations;
				loading.close();
			},
			// 删除地址辐射圈选中
			delAddressSelected(addressId) {
				const that = this
				let index = -1;
				for (let i = 0; i < that.address_circle_locations.length; i++) {
					if ('' + that.address_circle_locations[i].id === '' + addressId) {
						index = i;
						break;
					}
				}
				if (index != -1) that.address_circle_locations.splice(index, 1)
			},
			// 改变地址辐射圈半径
			changeAddressRadius(currentValue, oldValue) {
				const that = this
				const loading = common.showLoading()
				if ((that.address_circle_locations ||[]).length>0) {
					for (let item of that.address_circle_locations) {
						const gId = item.id;
						that.getEditorOverlay('qq-map-tool-circle').remove([gId]);
						that.afterDelPolygonOrCircleEditor(gId, 'circle');
						that.addCircle(item.location.lat, item.location.lng, currentValue, gId, item.title || '');
					}
				}
				loading.close()
			},
			// 新版地址搜索，关闭选择框
			closeAddressChooseDialog(){
				const that = this;
			},
			// 查询地址
			async searchAddressNew() {
				const that = this
			
				if (!that.searchForm.pca || that.searchForm.pca.length == 0) {
					common.message({
						message: '请选择省市',
						type: 'error'
					})
					return false
				}
				if (!that.searchForm.address) {
					common.message({
						message: '请输入地址',
						type: 'error'
					})
					return false
				}
				if (!that.address_radius) {
					common.message({
						message: '请输入地址辐射半径',
						type: 'error'
					})
					return false
				}
			
				that.$refs.addressSearch.searchAddressList({
					keyword: that.searchForm.address,
					boundary: that.searchForm.pca[that.searchForm.pca.length - 1]
				})
			},
			// 关闭地址tag
			closeAddressTag(index) {
				const that = this;
				that.address_circle_locations.splice(index, 1);
			},
			async exportChoosedList() {
				const that = this
				if(!that.chooseBuildingOnly){
					const count = (that.choosedBuildingAreas || []).length
					const point_types = (that.point_types_show_selected || []).map(id => {
						return that.point_types_map[id].name
					})
					if (count == 0) {
						common.messageError('请先选择项目!')
						return false
					}
					const confirm = await common.confirmDialog('您确认要导出项目信息?' +
						'<br/>时间段：<span class="text-red">' + that.dateRange[0].substring(0, 10) + ' ~ ' + that
						.dateRange[1].substring(0, 10) + '</span>' +
						'<br/>项目数量：<span class="text-red">' + count + '</span>' +
						'<br/>点位类型：<span class="text-red">' + (point_types || []).join('、') + '</span>')
					// if (confirm) export_building_list({
					// 	ids: (that.choosedBuildingAreas.map(item => item.id) || []).join(','),
					// 	point_type_ids: (that.point_types_show_selected || []).join(','),
					// 	start_at: that.dateRange[0],
					// 	end_at: that.dateRange[1]
					// })
					if (confirm) that.$emit('export-building', {
						building_ids: (that.choosedBuildingAreas.map(item => item.id) || []),
						media_type_ids: (that.point_types_show_selected || []),
						begin_date: that.dateRange[0],
						end_date: that.dateRange[1]
					});
				}else{
					that.$emit('export-building', (that.choosedBuildingAreas || []).map(b => {
						return {
							id: parseInt(b.id),
							dis_obj: b.dis_obj || {dis:0, title:''}
						}
					}));
				}
			},
			getMapCenter() {
				return new Promise((resolve, reject) => {
					get_map_center()
						.then(res => {
							const {
								code,
								data
							} = res
							if (code == 200) resolve(data)
							else resolve(null)
						})
						.catch(() => {
							resolve(null)
						})
				})
			},
			// 检查日期范围是否已选择
			checkDateRangeAvailable(_opt) {
				const that = this
				const opt = Object.assign(that.dateRange, _opt)
				return opt.dateRange && isArray(opt.dateRange) && opt.dateRange.length == 2 &&
					opt.dateRange[0] && opt.dateRange[1];
			},
			// 获取点位类型
			getPointTypes() {
				const that = this
				return get_media_types()
					.then(res => {
						const {
							code,
							data
						} = res
						if (code == 200) {
							// if (that.pointTypes && isArray(that.pointTypes) && that.pointTypes.length > 0) {
							// 	that.pointTypes.forEach(item => {
							// 		that.point_types_show[item] = true
							// 		that.point_types_show_selected.push(item)
							// 	})
							// } else {
							// 	data.forEach(item => {
							// 		that.point_types_show[item.id] = true
							// 		that.point_types_show_selected.push(item.id)
							// 	})
							// }
							
							data.forEach(item => {
								that.point_types_show[item.id] = false
								//that.point_types_show_selected.push(item.id)
							})
							data.forEach(item => {
								if(!!that.point_types_show[item.id]) item.show = true
							})
							that.point_types = data
							data.forEach(item => {
								that.point_types_map[item.id] = cloneDeep(item)
							})
						}
					})
			},
			// 开关切换名称显示
			changeShowLabel(e) {
				const that = this
				const show = ('' + e === '1')
				// if(that.mapObject.label) {
				// 	that.mapObject.label.setVisible(!!show)
				// 	//that.refreshLabel()
				// } 
				if (show) {
					if (that.mapObject.myLabelList) that.mapObject.myLabelList.forEach(item => {
						item.setMap(that.mapObject.map)
					})
				} else {
					if (that.mapObject.myLabelList) that.mapObject.myLabelList.forEach(item => {
						item.setMap(null)
					})
				}
			},
			// 开关切换标记点类型（普通和饼图）
			changeShowDonut(e) {
				const that = this
				if ('' + e === '1') {
					if (that.mapObject.marker) that.mapObject.marker.setMap(null)
					if (that.mapObject.donutList) that.mapObject.donutList.forEach(item => {
						item.setMap(that.mapObject.map)
					})
					that.refreshLabel()
				} else {
					if (that.mapObject.donutList) that.mapObject.donutList.forEach(item => {
						item.setMap(null)
					})
					if (that.mapObject.marker) that.mapObject.marker.setMap(that.mapObject.map)
					that.refreshLabel()
				}
			},
			// 开关切换媒体类型（废弃）
			changePointTypeShow(pointId, val) {
				const that = this
				let flag = that.point_types_show[pointId] == val
				if (!flag) {
					that.point_types_show[pointId] = val
					that.refreshMarkers()
				}
			},
			// 下拉框切换媒体类型
			changePointTypeShowSelect(val) {
				const that = this
				let shows = {}
				that.point_types.forEach(point => {
					shows[point.id] = false
				})
				that.point_types_show_selected.forEach(pointId => {
					shows[pointId] = true
				})
				that.point_types_show = Object.assign(that.point_types_show, shows);
				that.refreshMarkers()
			},
			// 经纬度点串查询接口仅对单个区划查询有效
			getAreaPolygon(code) {
				const that = this
				return new Promise(resolve => {
					area_search({
							keyword: code
						})
						.then(({
							data
						}) => {
							if (data.status == 0) {
								const polygon = (data.result[0])[0].polygon[0];
								let paths = [];
								if (polygon && isArray(polygon) && polygon.length > 0) {
									for (let i = 0; i < polygon.length; i += 2) {
										try {
											let latlng = new TMap.LatLng(polygon[i + 1], polygon[i])
											paths.push(latlng)
										} catch (e) {
											console.error(e)
										}
									}
								}
								resolve(paths)
							} else {
								resolve([])
							}
						})
						.catch(() => {
							resolve([])
						})
				})

			},
			// 改变省市
			changeCity(val) {
				const that = this
				const code = val[val.length - 1]
				const mapCenter = that.mapObject.map.getCenter()
				if (that.hasAreaSelect) {
					that.getAreaList(code)
						.then(() => {
							that.area_selected = []
						})
				}
				if (that.hasTradeAreaSelect) {
					that.getTradeAreas(code, mapCenter.getLat(), mapCenter.getLng())
						.then(() => {
							that.trade_area_selected = []
						})
				}
			},
			// 下拉框改变行政区划
			async changeAreaSelect(val) {
				const that = this
				const loading = common.showLoading({
					text: '加载中'
				})
				let compareR = compareArrayToGetDiffs(val, that.areaAll.map(x => x.value))
				if (compareR.less1 && isArray(compareR.less1) && compareR.less1.length > 0) {
					let ids = compareR.less1.filter(id => {
						const gId = 'area-' + id;
						if (that.mapToolIdAndBuildings[gId]) return true
						else return false;
					})
					that.getEditorOverlay('qq-map-tool-polygon').remove(ids.map(id => "area-" + id));
					ids.forEach(id => that.afterDelPolygonOrCircleEditor('area-' + id, 'polygon'));
				}
				if (compareR.same && isArray(compareR.same) && compareR.same.length > 0) {
					let ids = compareR.same.filter(id => {
						const gId = 'area-' + id;
						if (!that.mapToolIdAndBuildings[gId]) return true
						else return false;
					})
					for (let id of ids) {
						const gId = 'area-' + id;
						const paths = await that.getAreaPolygon(id)
						if (paths && isArray(paths) && paths.length > 0) {
							await that.addPolygon(paths, gId);
						}
					}
				}
				loading.close();
			},
			// 删除行政区划选中
			delAreaSelected(areaId) {
				const that = this
				let index = -1;
				for (let i = 0; i < that.area_selected.length; i++) {
					if ('' + that.area_selected[i] === '' + areaId) {
						index = i;
						break;
					}
				}
				if (index != -1) that.area_selected.splice(index, 1)
			},
			// 下拉框选中商圈
			async changeTradeAreaSelect(objs) {
				const that = this
				let lMap = new Map();
				(objs||[]).forEach(l => {
					lMap.set(l.id, l);
				})
				const loading = common.showLoading({
					text: '加载中'
				})
				
				const newIds = (objs || []).map(d => d.id);
				const oldIds = (that.tradeAreaAll || []).map(d => d.id);
				
				let compareR = compareArrayToGetDiffs(newIds, oldIds)
				//console.log(compareR)
				if ((compareR.less1 || []).length > 0 || (compareR.same || []).length > 0) {
					let ids = [...compareR.less1].filter(id => {
						const gId = 'trade-' + id;
						if (that.mapToolIdAndBuildings[gId]) return true
						else return false;
					})
					that.getEditorOverlay('qq-map-tool-circle').remove(ids.map(id => "trade-" + id));
					ids.forEach(id => that.afterDelPolygonOrCircleEditor('trade-' + id, 'circle'));
				}
				if ((compareR.over1 || []).length > 0 || (compareR.same || []).length > 0) {
					let ids = [...compareR.over1, ...compareR.same].filter(id => {
						const gId = 'trade-' + id;
						if (!that.mapToolIdAndBuildings[gId]) return true
						else return false;
					})
					for (let id of ids) {
						const gId = 'trade-' + id;
						const o = lMap.get(gId);
						if(!!o) that.addCircle(o.location.lat, o.location.lng, that.trade_area_radius, gId, o.title || '');
					}
				}
				loading.close();
			},
			// 删除商圈选中
			delTradeAreaSelected(tradeId) {
				const that = this
				let index = -1;
				for (let i = 0; i < that.trade_area_selected.length; i++) {
					if ('' + that.trade_area_selected[i].id === '' + tradeId) {
						index = i;
						break;
					}
				}
				if (index != -1) that.trade_area_selected.splice(index, 1)
			},
			// 改变商圈辐射半径
			changeTradeRadius(currentValue, oldValue) {
				const that = this
				const loading = common.showLoading()
				if ((that.trade_area_selected ||[]).length>0) {
					for (let item of that.trade_area_selected) {
						const gId = 'trade-' + item.id;
						that.getEditorOverlay('qq-map-tool-circle').remove([gId]);
						that.afterDelPolygonOrCircleEditor(gId, 'circle');
						that.addCircle(item.location.lat, item.location.lng, currentValue, gId);
					}
				}
				loading.close()
			},
			// 改变日期范围
			changeDateRange(val) {
				this.showBuildingAreas()
				this.exitEditor(false)
			},
			// ip定位地图中心
			async initPCAndMap() {
				const that = this;
				const laoding = common.showLoading({
					text: '定位中'
				})
				await that.getPCListAll()
				const {
					adcode,
					lat,
					lng,
					sw,
					ne
				} = await that.getMapCenter()
				laoding.close()
				that.initMap(lat, lng, sw, ne)
				that.searchForm.pca = getAdcodeListByAdcode(adcode)
				if (that.hasAreaSelect) that.getAreaList(that.searchForm.pca[that.searchForm.pca.length - 1])
				if (that.hasTradeAreaSelect) that.getTradeAreas(that.searchForm.pca[that.searchForm.pca.length - 1],
					lat, lng)
			},
			// 获取商圈列表
			getTradeAreas(adcode, lat, lng) {
				const that = this
				return search_trade_area({
						boundary: adcode,
						lat: lat,
						lng: lng
					})
					.then(({
						data
					}) => {
						that.tradeAreaAll = data
					})
			},
			// 获取所有省市
			getPCListAll() {
				const that = this
				return new Promise((resolve, reject) => {
					pc_list_all()
						.then(res => {
							const {
								code,
								data
							} = res
							if (code == 200) {
								if (data && data.length > 0) {
									that.pcAll = data
									resolve()
								}
							}
						})
				})

			},
			// 获取pid下所有区
			getAreaList(pid) {
				const that = this
				return area_list({
						pid: pid
					})
					.then(({
						data
					}) => {
						that.areaAll = data
					})
			},
			// 获取ip定位
			getIPLocation() {
				const that = this
				return new Promise((resolve, reject) => {
					ip_location()
						.then(res => {
							const {
								code,
								data: {
									status,
									result
								}
							} = res
							if (code == 200 && status == 0) {
								resolve(result)
							}
						})
				})
			},
			// 初始化地图
			initMap(lat, lng, sw, ne) {
				const that = this
				if (that.mapObject.map) {
					that.mapObject.map.destroy()
					that.mapObject = {}
				}
				that.mapObject.center = new TMap.LatLng(lat, lng)
				that.mapObject.container = document.getElementById('qq-map-container')
				that.mapObject.map = new TMap.Map(that.mapObject.container, {
					center: that.mapObject.center,
					zoom: that.mapDefaultZoom
				})
				if (sw && ne) {
					// 自动缩放
					// setTimeout(function() {
					// 	let bounds = new TMap.LatLngBounds(new TMap.LatLng(sw.lat, sw.lng), new TMap.LatLng(ne.lat,
					// 		ne.lng));
					// 	that.mapObject.map.fitBounds(bounds, {
					// 		padding: {
					// 			top: 100,
					// 			bottom: 50,
					// 			left: 20,
					// 			right: 100
					// 		},
					// 		maxZoom: that.mapDefaultZoom
					// 	})
					// }, 2000)
				}
				that.initMapInfoWindow() // 初始化信息窗体
				that.initMapEditor() // 初始化编辑器
				that.listenToMouseClick() // 监听鼠标点击
				that.listenToMouseMove() // 监听鼠标移动
				that.listenToMapPanEnd() // 监听地图平移结束
				that.listenToMapZoomChanged() // 监听地图缩放完成
				that.showBuildingAreas({first: true}) // 渲染项目标记点
				// 地图缩放控件，放至右下角
				that.mapObject.ZOOMControl = that.mapObject.map.getControl(TMap.constants.DEFAULT_CONTROL_ID.ZOOM);
				that.mapObject.ZOOMControl.setPosition(TMap.constants.CONTROL_POSITION.BOTTOM_RIGHT);
			},
			// 初始化信息窗体
			initMapInfoWindow() {
				const that = this
				that.mapObject.infoWindow = new TMap.InfoWindow({
					map: that.mapObject.map,
					position: that.mapObject.center,
					zIndex: 100,
					offset: {
						x: 0,
						y: -47
					} //设置信息窗相对position偏移像素
				});
				that.mapObject.infoWindow.close();
			},
			// 监听鼠标在地图点击
			listenToMouseClick() {
				const that = this
				that.mapObject.map.on("click", function(evt) {
					that.$nextTick(() => {
						if (that.mapToolActiveType === 'qq-map-tool-circle' && !that
							.mapToolCircleRadiusDisShow) {
							that.mapToolCircleRadiusDisPoint = cloneDeep(evt.point)
							that.mapToolCircleRadiusDisPosition = {
								top: (evt.point.y + 40 + (that.$store.getters.tagsView ? 34 : 0)),
								left: (evt.point.x - 40)
							}
						}
					})
				})
			},
			// 监听鼠标在地图移动
			listenToMouseMove() {
				const that = this
				/* that.mapObject.map.on("mousemove", function(evt){
					if(that.mapToolCircleRadiusDisShow){
						that.$nextTick(() =>{
						    that.mapToolCircleRadiusDisPoint = cloneDeep(evt.point)
						    that.mapToolCircleRadiusDisPosition = {
						    	top: (evt.point.y+84),
						    	left: (evt.point.x+10)
						    }
						})
					}
				}) */
			},
			// 监听地图平移完成
			listenToMapPanEnd() {
				const that = this
				// 监听平移
				// that.mapObject.map.on("panend", function() {
				// 	that.loadingBuildingAreas()
				// })
			},
			// 监听地图缩放完成
			listenToMapZoomChanged() {
				const that = this
				// 监听平移
				// that.mapObject.map.on("zoom_changed", function() {
				// 	that.loadingBuildingAreas(true)
				// })
			},
			// 显示项目标记
			showBuildingAreas(_opt) {
				const that = this
				const opt = Object.assign({
					showLoading: true,
					dateRange: ['', '']
				}, {
					dateRange: that.dateRange
				}, _opt)
				const first = !!opt.first
				let loading = null
				if (opt.showLoading) loading = common.showLoading({
					text: '加载项目中'
				})
				var mapBounds = that.mapObject.map.getBounds(); //获取当前地图的视野范围
				if (mapBounds) {
					let params = {
						sw_lat: mapBounds.getSouthWest().getLat().toFixed(6),
						sw_lng: mapBounds.getSouthWest().getLng().toFixed(6),
						ne_lat: mapBounds.getNorthEast().getLat().toFixed(6),
						ne_lng: mapBounds.getNorthEast().getLng().toFixed(6)
					}
					if (that.checkDateRangeAvailable(opt)) {
						params.start_at = opt.dateRange[0]
						params.end_at = opt.dateRange[1]
					}
					if(!that.chooseBuildingOnly){
						building_area_list(params)
							.then(res => {
								const {
									code,
									data
								} = res
								if (code == 200) {
									let builds = {};
									data.forEach(b => {
										builds[''+b.id] = cloneDeep(b);
									})
									that.buildingAreas = Object.assign(that.buildingAreas, builds);
									that.choosedBuildingAreas = [];
									that.createMarker(data)
									//that.createDonut(data)
									//that.createLabel(data)
									that.createMyLabel(data)
								}
								if (loading && isFunction(loading.close)) loading.close()
							})
							.catch(() => {
								if (loading && isFunction(loading.close)) loading.close()
							})
					}else{
						building_area_for_point_plan_map(params)
							.then(res => {
								const {
									code,
									data
								} = res
								if (code == 200) {
									(data || []).forEach(d => {
										let first_char = '';
										try{
											first_char = pinyin.getWordsCode(d.name) || '';
										}catch(err){}
										if(!!first_char) {
											d.first_char = first_char.toUpperCase();
										}else{
											d.first_char = '';
										}
									});
									that.createMarker(data)
									//that.createDonut(data)
									//that.createLabel(data)
									that.createMyLabel(data)
								}
								if (loading && isFunction(loading.close)) loading.close()
							})
							.catch(() => {
								if (loading && isFunction(loading.close)) loading.close()
							})
					}
					
				}
			},
			// 专门提供给平移、缩放地图调用，重新渲染项目
			loadingBuildingAreas(useTimeout) {
				const that = this

				function callback() {
					that.showBuildingAreas({
						showLoading: false
					})
				}
				if (useTimeout) {
					// 考虑到缩放地图，会以极短的时间间隔，多次触发事件。此处利用开关和延时，事件触发2秒后再拉取视野内项目
					if (!that.zoomLoadingFlag) {
						that.zoomLoadingFlag = true
						setTimeout(function() {
							that.zoomLoadingFlag = false
							callback()
						}, 2000)
					}
				} else {
					callback()
				}
			},

			// 全部点位类型都开启与否
			allPointTypeShow() {
				const that = this
				let flag = true;
				const pointIdKeys = Object.keys(that.point_types_show)
				if (pointIdKeys && isArray(pointIdKeys)) {
					for (let i in that.point_types_show) {
						flag = flag && that.point_types_show[i]
					}
				}
				return flag
			},

			// 创建普通标记点
			createMarker(datas) {
				const that = this
				//console.log(datas)
				return new Promise(resolve => {
					let choosedMarker = {}
					if (that.choosedBuildingAreas && isArray(that.choosedBuildingAreas)) {
						that.choosedBuildingAreas.forEach(item => {
							choosedMarker['' + item.id] = item
						})
					}

					let zeroFlag = (that.zeroShow && !that.zeroShowExceptPointTypeSwitch) ||
						(that.zeroShow && that.zeroShowExceptPointTypeSwitch && that.allPointTypeShow());
						
					function getStyleId(id, type_id){
						if(''+type_id === '78') return choosedMarker['' + id] ? 'marker_choosed' : 'marker';
						else if(''+type_id === '79') return choosedMarker['' + id] ? 'marker22' : 'marker21';
						else if(''+type_id === '80') return choosedMarker['' + id] ? 'marker32' : 'marker31';
						else if(''+type_id === '81') return choosedMarker['' + id] ? 'marker42' : 'marker41';
						else if(''+type_id === '82') return choosedMarker['' + id] ? 'marker92' : 'marker91';
						else if(''+type_id === '83') return choosedMarker['' + id] ? 'marker102' : 'marker101';
						else if(''+type_id === '84') return choosedMarker['' + id] ? 'marker112' : 'marker111';
						else if(''+type_id === '85') return choosedMarker['' + id] ? 'marker122' : 'marker121';
						else if(''+type_id === '86') return choosedMarker['' + id] ? 'marker42' : 'marker41';
						else return choosedMarker['' + id] ? 'marker_choosed' : 'marker';
					}

					function generateMarkerGeometry(item) {
						let sum = that.calculUsedSum(item)
						if (!sum.show && !zeroFlag) {
							return {
								"id": 'marker' + item.id,
								"result": -1
							}
						} else {
							return {
								"id": 'marker' + item.id,
								"styleId": getStyleId(item.id, item.type_id),
								"position": new TMap.LatLng(parseFloat(item.lat || 0), parseFloat(item.lng || 0)),
								"properties": {
									"title": "marker"
								}
							}
						}

					}
					
					function genMarkerArrs(list){
						let removeIds = [];
						let addGeometries = [];
						let allGeometries = [];
						let addBuilds = {};
						
						if((list || []).length > 0){
							list.forEach(item => {
								const markId = 'marker' + item.id;
								let sum = that.calculUsedSum(item);
								//console.log('sum.show', sum.show);
								//console.log('zeroFlag', zeroFlag);
								if(!sum.show && !zeroFlag) {
									removeIds.push(markId);
								} else {
									const curMarker = {
											"id": markId,
											"styleId": getStyleId(item.id, item.type_id),
											"position": new TMap.LatLng(parseFloat(item.lat || 0), parseFloat(item.lng || 0)),
											"properties": {"title": "marker"}
									}
									allGeometries.push(curMarker);
									addBuilds[''+item.id] = item;
									// if (!!that.mapObject.marker) {
									// 	const cur = that.mapObject.marker.getGeometryById(markId);
									// 	if(!cur) {
									// 		addGeometries.push(curMarker);
									// 		addBuilds[''+item.id] = item;
									// 	}
									// } else {
									// 	addGeometries.push(curMarker);
									// 	addBuilds[''+item.id] = item;
									// }
								}
							})
							
						}
						return {
							removeIds,
							addGeometries,
							allGeometries,
							addBuilds
						}
					}

					if (isArray(datas) && datas.length > 0) {
						const {removeIds, addGeometries, allGeometries, addBuilds} = genMarkerArrs(datas);
						
						//console.log(removeIds, addGeometries, allGeometries, addBuilds)
						if (that.mapObject.marker) {
							that.mapObject.marker.remove(removeIds)
						}
						if (!that.mapObject.marker) {
							const d_style = {
								"width": 18,
								"height": 24
							};
							const style = {
								"width": 24,
								"height": 24
							};
							that.mapObject.marker = new TMap.MultiMarker({
								id: 'marker-layer',
								map: ('' + that.showDonut === '1' ? null : that.mapObject.map),
								styles: {
									"marker": new TMap.MarkerStyle(Object.assign(d_style, {
										"src": mapMarker
									})),
									"marker_choosed": new TMap.MarkerStyle(Object.assign(d_style, {
										"src": mapChoosedMarker
									})),
									"marker11": new TMap.MarkerStyle(Object.assign(style, {
										"src": mapMarker11
									})),
									"marker12": new TMap.MarkerStyle(Object.assign(style, {
										"src": mapMarker12
									})),
									"marker21": new TMap.MarkerStyle(Object.assign(style, {
										"src": mapMarker21
									})),
									"marker22": new TMap.MarkerStyle(Object.assign(style, {
										"src": mapMarker22
									})),
									"marker31": new TMap.MarkerStyle(Object.assign(style, {
										"src": mapMarker31
									})),
									"marker32": new TMap.MarkerStyle(Object.assign(style, {
										"src": mapMarker32
									})),
									"marker41": new TMap.MarkerStyle(Object.assign(style, {
										"src": mapMarker41
									})),
									"marker42": new TMap.MarkerStyle(Object.assign(style, {
										"src": mapMarker42
									})),
									"marker91": new TMap.MarkerStyle(Object.assign(style, {
										"src": mapMarker91
									})),
									"marker92": new TMap.MarkerStyle(Object.assign(style, {
										"src": mapMarker92
									})),
									"marker101": new TMap.MarkerStyle(Object.assign(style, {
										"src": mapMarker101
									})),
									"marker102": new TMap.MarkerStyle(Object.assign(style, {
										"src": mapMarker102
									})),
									"marker111": new TMap.MarkerStyle(Object.assign(style, {
										"src": mapMarker111
									})),
									"marker112": new TMap.MarkerStyle(Object.assign(style, {
										"src": mapMarker112
									})),
									"marker121": new TMap.MarkerStyle(Object.assign(style, {
										"src": mapMarker121
									})),
									"marker122": new TMap.MarkerStyle(Object.assign(style, {
										"src": mapMarker122
									})),
								},
								geometries: allGeometries
							});
						} else {
							that.mapObject.marker.updateGeometries(allGeometries);
						}
						
						that.calChoosedBuildingAreasSum()
						that.listenToMarkerClick()
						
						// if (!that.mapObject.marker) {
						// 	that.mapObject.marker = new TMap.MarkerCluster({
						// 		id: 'cluster',
						// 		map: ('' + that.showDonut === '1' ? null : that.mapObject.map),
						// 		enableDefaultStyle: true, // 启用默认样式
						// 		minimumClusterSize: 2, // 形成聚合簇的最小个数
						// 		geometries: allGeometries,
						// 		zoomOnClick: true, // 点击簇时放大至簇内点分离
						// 		gridSize: 60, // 聚合算法的可聚合距离
						// 		averageCenter: false, // 每个聚和簇的中心是否应该是聚类中所有标记的平均值
						// 		maxZoom: 13 // 采用聚合策略的最大缩放级别
						// 	});
						// }else{
						// 	that.mapObject.marker.updateGeometries(allGeometries);
						// }
					}
					
					resolve()
				})
			},
			// 监听点击标记点
			listenToMarkerClick() {
				const that = this
				// 监听标注点击事件
				// 判断编辑器图层是否活跃，活跃则不显示信息窗体
				that.mapObject.marker.on("click", function(evt) {
					const id = evt.geometry.id.substring(6)
					let activeOverlay = null
					if (that.mapObject.editor) {
						activeOverlay = that.mapObject.editor.getActiveOverlay()
					}
					if (!activeOverlay) {
						that.showInfoWindow(id, evt.geometry.position)
					}
				})
			},

			// 计算已安装数（废弃）
			getInstalledSum(item) {
				const that = this
				let bSum = 0
				const media = item.installed_media || {}
				const keys = Object.keys(item.installed_media)
				if (isArray(keys) && keys.length > 0 && that.pointTypes.length > 0) {
					that.pointTypes.forEach(pointId => {
						if (media[pointId] && ((media[pointId].num || 0) > 0)) bSum = accAdd(bSum || 0, media[
							pointId].num || 0)
					})
				}
				return bSum
			},

			// 根据已选中项目，计算选中的总数和各点位类型总数
			calChoosedBuildingAreasSum() {
				const that = this
				// 清空数据
				that.choosedBuildingAreasSum = {
					sum: {
						used: 0,
						locked: 0,
						can: 0
					},
					pointTypes: {
						used: {},
						locked: {},
						can: {}
					}
				}
				const pointTypeKeys = Object.keys(that.point_types_show)
				pointTypeKeys.forEach(pointId => {
					if (that.point_types_show[pointId]) {
						that.choosedBuildingAreasSum.pointTypes.used[pointId] = 0
						that.choosedBuildingAreasSum.pointTypes.locked[pointId] = 0
						that.choosedBuildingAreasSum.pointTypes.can[pointId] = 0
					}
				})
				let resultChoosedBuildingAreas = []
				let resultSum = cloneDeep(that.choosedBuildingAreasSum)
				if (that.choosedBuildingAreas && isArray(that.choosedBuildingAreas)) {
					const building_sum_keys = Object.keys(that.building_sum)
					if (building_sum_keys && isArray(building_sum_keys)) {
						const curPointIds = Object.keys(resultSum.pointTypes.can)
						if (curPointIds && isArray(curPointIds)) {
							let b_pointTypes = {
								used: {},
								locked: {},
								can: {},
								device_size: {}
							};
							let deviceSizesObj = {}
							that.choosedBuildingAreas.forEach(building => {
								let dss = building.device_size;
								if ((building.device_size || 0).length > 0) {
									building.device_size.forEach(s => {
										const key = s.point_type_id + '_' + s.size
										let o = deviceSizesObj[key];
										if (!o) {
											o = JSON.parse(JSON.stringify(s));
										} else {
											o.count += parseInt(s.count);
										}
										deviceSizesObj[key] = JSON.parse(JSON.stringify(o));
									})
								}

								let b_used = 0,
									b_locked = 0,
									b_can = 0;
								curPointIds.forEach(pointId => {
									let used = that.building_sum[building.id].pointTypes.used[pointId] || 0
									let locked = that.building_sum[building.id].pointTypes.locked[
										pointId] || 0
									let can = that.building_sum[building.id].pointTypes.can[pointId] || 0
									if (!b_pointTypes.used[pointId]) b_pointTypes.used[pointId] = 0
									if (!b_pointTypes.locked[pointId]) b_pointTypes.locked[pointId] = 0
									if (!b_pointTypes.can[pointId]) b_pointTypes.can[pointId] = 0
									b_pointTypes.used[pointId] += used;
									b_pointTypes.locked[pointId] += locked;
									b_pointTypes.can[pointId] += can;
									b_used += used;
									b_locked += locked;
									b_can += can;
								})
								if (b_can > 0) {
									resultChoosedBuildingAreas.push(JSON.parse(JSON.stringify(building)))
									resultSum.sum.used += b_used;
									resultSum.sum.locked += b_locked;
									resultSum.sum.can += b_can;
								}
							})
							for (const key of Object.keys(deviceSizesObj || {})) {
								const keys = key.split('_')
								let cur = deviceSizesObj[key],
									curList = []
								if (cur) {
									curList = b_pointTypes.device_size[keys[0]] || []
									curList.push(JSON.parse(JSON.stringify(cur)))
									b_pointTypes.device_size[keys[0]] = JSON.parse(JSON.stringify(curList))
								}
							}
							if (resultSum.sum.can > 0) {
								resultSum.pointTypes = cloneDeep(b_pointTypes)
							}
						}
					}
				}
				that.choosedBuildingAreas = JSON.parse(JSON.stringify(resultChoosedBuildingAreas))
				that.choosedBuildingAreasSum = JSON.parse(JSON.stringify(resultSum))
			},

			// 计算数量(已用、锁定、空闲)
			calculUsedSum(building) {
				const that = this
				let sum = {
					used: 0,
					locked: 0,
					can: 0,
					num: 0,
					pointTypes: { // 点位类型对应数量
						used: {},
						locked: {},
						can: {},
						num: {},
					}
				}

				const pointTypeKeys = Object.keys(that.point_types_show)
				pointTypeKeys.forEach(pointId => {
					if (that.point_types_show[pointId]) {
						if (!building.point_num_sum[pointId]) {
							building.point_num_sum[pointId] = {
								installed_num: 0,
								uninstalled_num: 0,
								num: 0,
								used_num: 0,
								locked_num: 0,
								available_num: 0,
								movable_num: 0
							}
						}
						if (that.showInstalledNum) { //仅显示已安装数（目前只有巡检项目相关）
							let temp = parseInt(building.point_num_sum[pointId].installed_num || 0);
							sum.can = accAdd(sum.can, temp);
							sum.num = accAdd(sum.num, temp);
							sum.pointTypes.can[pointId] = temp;
							sum.pointTypes.num[pointId] = temp;
						} else if (that.showUninstalledNum) { //仅显示未安装数（目前只有新安装项目相关）
							let temp = parseInt(building.point_num_sum[pointId].uninstalled_num || 0);
							sum.can = accAdd(sum.can, temp);
							sum.num = accAdd(sum.num, temp);
							sum.pointTypes.can[pointId] = temp;
							sum.pointTypes.num[pointId] = temp;
						} else { // 用于锁定、合同
							let temp1 = parseInt(building.point_num_sum[pointId].num || 0);
							let temp2 = parseInt(building.point_num_sum[pointId].used_num || 0);
							let temp3 = parseInt(building.point_num_sum[pointId].locked_num || 0);
							let temp4 = parseInt(building.point_num_sum[pointId].available_num || 0);
							let temp5 = parseInt(building.point_num_sum[pointId].movable_num || 0);
							sum.num = accAdd(sum.num, temp1);
							sum.used = accAdd(sum.used, temp2);
							sum.locked = accAdd(sum.locked, temp3);
							sum.can = accAdd(sum.can, accAdd(temp4, temp5));
							sum.pointTypes.num[pointId] = temp1;
							sum.pointTypes.used[pointId] = temp2;
							sum.pointTypes.locked[pointId] = temp3;
							sum.pointTypes.can[pointId] = accAdd(temp4, temp5);
						}
					}
				})
				sum.show = (sum.used + sum.locked + sum.can) > 0
				that.building_sum[building.id] = cloneDeep(sum)
				return sum
			},
			// 创建饼图标记点
			createDonut(datas) {
				const that = this

				return new Promise(resolve => {
					let zeroFlag = (that.zeroShow && !that.zeroShowExceptPointTypeSwitch) ||
						(that.zeroShow && that.zeroShowExceptPointTypeSwitch && that.allPointTypeShow())

					function generateDonutOptions(item) {
						let sum = that.calculUsedSum(item)
						let index = 0;
						if (sum.num >= 50) index = 1;
						if (sum.num >= 100) index = 2;

						if (!sum.show && !zeroFlag) {
							return -1
						} else {
							return {
								id: 'donut' + item.id,
								map: ('' + that.showDonut === '1' ? that.mapObject.map : null),
								position: new TMap.LatLng(item.lat, item.lng),
								data: [sum.used, sum.locked, sum.can], // [已用数，锁定数，空闲数]
								minRadius: that.donutSize[index].minRadius,
								maxRadius: that.donutSize[index].maxRadius
							}
						}
					}

					if (isArray(datas) && datas.length > 0) {
						if (isArray(that.mapObject.donutList) && that.mapObject.donutList.length > 0) {
							that.mapObject.donutList.forEach(item => {
								item.setMap(null)
							})
						}
						that.mapObject.donutList = datas.filter(item => {
							const m = generateDonutOptions(item)
							return m != -1
						}).map(item => {
							that.buildingAreas['' + item.id] = item;
							return new Donut(generateDonutOptions(item))
						})
						that.calChoosedBuildingAreasSum()
						that.listenToDonutClick()
					}

					resolve()
				})
			},
			// 监听饼图点击
			listenToDonutClick() {
				const that = this
				if (isArray(that.mapObject.donutList) && that.mapObject.donutList.length > 0) {
					that.mapObject.donutList.forEach((donut, index) => {
						donut.on('click', () => {
							let activeOverlay = null
							if (that.mapObject.editor) {
								activeOverlay = that.mapObject.editor.getActiveOverlay()
							}
							if (!activeOverlay) {
								that.showInfoWindow(donut.id.substring(5), donut.position)
							}
						});
					});
				}
			},
			// 创建自定义名称
			createMyLabel(datas) {
				const that = this
				return new Promise(resolve => {
					const lefts = [28, 35, 42]

					let zeroFlag = (that.zeroShow && !that.zeroShowExceptPointTypeSwitch) ||
						(that.zeroShow && that.zeroShowExceptPointTypeSwitch && that.allPointTypeShow())

					function generateMyLabelOptions(item) {
						let sum = that.calculUsedSum(item)
						let index = 0;
						if (sum.num >= 50) index = 1;
						if (sum.num >= 100) index = 2;
						if (!sum.show && !zeroFlag) {
							return -1
						} else {
							return {
								id: 'label' + item.id,
								map: ('' + that.showLabel === '1' ? that.mapObject.map : null),
								position: new TMap.LatLng(item.lat, item.lng),
								content: item.name,
								left: ('' + that.showDonut === '1' ? lefts[index] : 15),
								top: ('' + that.showDonut === '1' ? -10 : -22)
							}
						}
					}


					if (isArray(datas) && datas.length > 0) {
						if (isArray(that.mapObject.myLabelList) && that.mapObject.myLabelList.length > 0) {
							that.mapObject.myLabelList.forEach(item => {
								item.setMap(null)
							})
							that.mapObject.myLabelList = []
						}
						that.mapObject.myLabelList = datas.filter(item => {
							const m = generateMyLabelOptions(item)
							return m != -1
						}).map(item => {
							return new MyLabel(generateMyLabelOptions(item))
						})
						that.calChoosedBuildingAreasSum()
					}
					resolve()
				})
			},
			// 创建名称
			createLabel(datas) {
				const that = this

				let choosedMarker = {}
				if (that.choosedBuildingAreas && isArray(that.choosedBuildingAreas)) {
					that.choosedBuildingAreas.forEach(item => {
						choosedMarker['' + item.id] = item
					})
				}
				
				let zeroFlag = (that.zeroShow && !that.zeroShowExceptPointTypeSwitch) ||
					(that.zeroShow && that.zeroShowExceptPointTypeSwitch && that.allPointTypeShow())

				function generateLabelGeometry(item) {
					let sum = that.calculUsedSum(item);
					//console.log(sum.show);
					//console.log('zeroFlag', zeroFlag);
					const id = 'label' + item.id;
					if(!sum.show && !zeroFlag) {
						return {
							"id": id,
							"result": -1
						}
					} else {
						let index = 2;
						if (item.point_sum >= 50) index = 3;
						if (item.point_sum >= 100) index = 4;
						return {
							"id": id,
							"styleId": (('' + that.showDonut === '1') ? ('label' + index) : 'label') + (choosedMarker['' + item
								.id] ? '_choosed' : ''),
							"position": new TMap.LatLng(item.lat, item.lng),
							'content': item.name, //标注文本
							"properties": {
								"title": "label"
							},
							"rank": parseInt(index || 1)
						}
					}
					
				}
				
				if (isArray(datas) && datas.length > 0) {
					let removeIds = [];
					const geometries = datas.map(item => {
						return generateLabelGeometry(item)
					}).filter(item => {
						const flag = item.result !== -1;
						if(!flag) removeIds.push(item.id);
						return flag;
					}) || [];
					//console.log('geometries', geometries);
					
					if (that.mapObject.label) {
						that.mapObject.label.remove(removeIds)
					}
					
					if (!that.mapObject.label) {
						const fontColor = '#606266';
						const fontColorChoosed = '#fbbd08';
						const offset1 = {x:0, y:12};
						const offset2 = {x:0, y:30};
						const offset3 = {x:0, y:38};
						const offset4 = {x:0, y:46};
						
						const defaulStyle = {
							'size': 14, //文字大小属性
							'backgroundColor': '#FFFFFF',
							'padding': '2px 10px',
							'borderWidth': 1,
							'borderRadius': 6,
							'borderColor': '#DDDDDD'
						}; 
						that.mapObject.label = new TMap.MultiLabel({
							id: 'label-layer',
							map: that.mapObject.map,
							enableCollision: true,
							styles: {
								'label': new TMap.LabelStyle(
								Object.assign(defaulStyle, {
									'color': fontColor,
									'offset': offset1
								})),
								'label_choosed': new TMap.LabelStyle(
								Object.assign(defaulStyle, {
									'color': fontColorChoosed,
									'offset': offset1
								})),
								'label2': new TMap.LabelStyle(
								Object.assign(defaulStyle, {
									'color': fontColor,
									'offset': offset2
								})),
								'label2_choosed': new TMap.LabelStyle(
								Object.assign(defaulStyle, {
									'color': fontColorChoosed,
									'offset': offset2
								})),
								'label3': new TMap.LabelStyle(
								Object.assign(defaulStyle, {
									'color': fontColor,
									'offset': offset3
								})),
								'label3_choosed': new TMap.LabelStyle(
								Object.assign(defaulStyle, {
									'color': fontColorChoosed,
									'offset': offset3
								})),
								'label4': new TMap.LabelStyle(
								Object.assign(defaulStyle, {
									'color': fontColor,
									'offset': offset4
								})),
								'label4_choosed': new TMap.LabelStyle(
								Object.assign(defaulStyle, {
									'color': fontColorChoosed,
									'offset': offset4
								}))
							},
							geometries: geometries
						});
					} else {
						that.mapObject.label.updateGeometries(geometries)
					}
					that.mapObject.label.setVisible(''+that.showLabel === '1');
				}
			},
			// 用已缓存的项目数据，刷新标记和文本
			refreshMarkers(beforeLoading) {
				const that = this
				let datas = []
				let loading = null;
				if (!beforeLoading) {
					loading = common.showLoading()
				} else {
					loading = beforeLoading
				}
				if (that.buildingAreas && isObject(that.buildingAreas)) {
					datas = Object.values(that.buildingAreas).map(item => (cloneDeep(item)))
					Promise.all([
						that.createMarker(datas), 
						//that.createDonut(datas), 
						//that.createLabel(datas), 
						that.createMyLabel(datas)
					])
					.then(() => {
						loading.close();
					})
					.catch(() => {
						loading.close();
					})
					// that.createMarker(datas)
					// that.createDonut(datas)
					// that.createMyLabel(datas)
				} else {
					loading.close();
				}
			},
			// 用已缓存的项目数据，刷新文本
			refreshLabel() {
				const that = this
				let datas = []
				if (that.buildingAreas && isObject(that.buildingAreas)) {
					datas = Object.values(that.buildingAreas).map(item => (cloneDeep(item)))
					//that.createLabel(datas)
					that.createMyLabel(datas)
				}
			},
			// 显示信息窗体
			showInfoWindow(areaId, position) {
				const that = this
				//设置infoWindow
				that.mapObject.infoWindow.open(); //打开信息窗
				that.mapObject.infoWindow.setPosition(position); //设置信息窗位置
				const info = that.buildingAreas['' + areaId];
				console.log('info',info);
				let contentHTML = '<div class="padding-lr-sm" style="min-width:300px">' +
					'	<div class="text-center padding-bottom-sm margin-bottom-sm solid-bottom">' +
					'		<div class="text-lg text-bold">' + info.name + '</div>' +
					'	</div>' +
					'	<div class="text-sm padding-bottom-sm margin-bottom-sm solid-bottom">' +
					'		<div class="flex justify-between align-center margin-top-xs">' +
					'			<div>均价：</div>' +
					'			<div>' +
					'				<span>' + (info.price ? info.price : '-') + '</span>' +
					'				<span class="text-gray">元 / 平方</span>' +
					'			</div>' +
					'		</div>';
				if(that.showCounts){
					/* if (isArray(that.pointTypes) && that.pointTypes.length > 0) {
						if (that.showInstalledNum) {
							for (const pointId of that.pointTypes) {
								contentHTML += '		<div class="flex justify-between align-center margin-top-xs">' +
									'			<div>' + that.point_types_map[pointId].name + '：</div>' +
									'			<div class="text-bold">' +
									'				<span class="text-blue">已装:' + (info.installed_media[pointId] ? info.installed_media[
										pointId].num : 0) + '</span>' +
									'			</div>' +
									'		</div>';
							}
						} else if (that.showUninstalledNum) {
							for (const pointId of that.pointTypes) {
								contentHTML += '		<div class="flex justify-between align-center margin-top-xs">' +
									'			<div>' + that.point_types_map[pointId].name + '：</div>' +
									'			<div class="text-bold">' +
									'				<span class="text-blue">未装:' + (info.point_num_sum[pointId] ? info.point_num_sum[
										pointId].uninstalled_num : 0) + '</span>' +
									'			</div>' +
									'		</div>';
							}
						}
					} 
					else {
						if (isArray(info.point_dianti)) {
							for (const point of info.point_dianti) {
								contentHTML += '		<div class="flex justify-between align-center margin-top-xs">' +
									'			<div>' + point.point_type + '：</div>' +
									'			<div class="text-bold">' +
									'				<span class="text-red">' + that.countPointTypeName[0] + ':' + point.used_num +
									'</span>' +
									'				<span> / </span>' +
									'				<span class="text-orange">' + that.countPointTypeName[1] + ':' + point.locked_num +
									'</span>' +
									'				<span> / </span>' +
									'				<span class="text-blue">' + that.countPointTypeName[2] + ':' + (point.movable_num +
										point.available_num) + '</span>' +
									'			</div>' +
									'		</div>';
							}
						}
						if (isArray(info.point_churukou)) {
							for (const point of info.point_churukou) {
								contentHTML += '		<div class="flex justify-between align-center margin-top-xs">' +
									'			<div>' + point.point_type + '：</div>' +
									'			<div class="text-bold">' +
									'				<span class="text-red">' + that.countPointTypeName[0] + ':' + point.used_num +
									'</span>' +
									'				<span> / </span>' +
									'				<span class="text-orange">' + that.countPointTypeName[1] + ':' + point.locked_num +
									'</span>' +
									'				<span> / </span>' +
									'				<span class="text-blue">' + that.countPointTypeName[2] + ':' + (point.movable_num +
										point.available_num) + '</span>' +
									'			</div>' +
									'		</div>';
							}
						}
					} */
					(that.point_types || []).forEach(point => {
						if(!!(info.point_num_sum[''+point.id] || {}).num){
							contentHTML += '		<div class="flex justify-between align-center margin-top-xs">' +
								'			<div>' + point.name + '：</div>' +
								'			<div class="text-bold">' +
								'				<span class="text-red">' + that.countPointTypeName[0] + ':' + info.point_num_sum[''+point.id].used_num +
								'</span>' +
								'				<span> / </span>' +
								'				<span class="text-orange">' + that.countPointTypeName[1] + ':' + info.point_num_sum[''+point.id].locked_num +
								'</span>' +
								'				<span> / </span>' +
								'				<span class="text-blue">' + that.countPointTypeName[2] + ':' + (info.point_num_sum[''+point.id].movable_num +
									info.point_num_sum[''+point.id].available_num) + '</span>' +
								'			</div>' +
								'		</div>';
						}
					})
				}

				contentHTML += '	</div>';
				if (that.hasInfoEdit || that.hasInfoDel || that.hasChoose) {
					contentHTML += '	<div class="flex justify-between align-center text-sm">';
					if (that.hasInfoEdit) {
						contentHTML +=
							'		<el-button class="text-blue info-operate" type="text" id="info-window-edit">编辑</el-button>';
					}
					if (that.hasInfoDel) {
						contentHTML +=
							'		<el-button class="text-red info-operate" type="text" id="info-window-del">删除</el-button>';
					}
					if (that.hasChoose && (that.mapToolActiveType === 'qq-map-tool-locate' ||
							that.mapToolActiveType === 'qq-map-tool-polygon' ||
							that.mapToolActiveType === 'qq-map-tool-circle' ||
							that.mapToolActiveType === 'qq-map-tool-delete')) {
						contentHTML +=
							'		<el-button class="text-green info-operate" type="text" id="info-window-addChoose">加入待选</el-button>';
					}
					contentHTML += '	</div>';
				}
				contentHTML += '</div>';
				that.mapObject.infoWindow.setContent(contentHTML); //设置信息窗内容
				that.curInfo = JSON.parse(JSON.stringify(info))
				that.listenToInfoWindowClick()
			},
			// 监听信息窗体点击
			listenToInfoWindowClick() {
				const that = this
				if (that.hasInfoEdit && !that.infoWindowEdit) {
					if (window.document.getElementById("info-window-edit"))
						that.infoWindowEdit = window.document.getElementById("info-window-edit").addEventListener('click',
							function(e) {
								let info = cloneDeep(that.curInfo)
								that.mapObject.infoWindow.close()
								that.$emit('info-edit', info) // 通知父组件编辑信息
							})
				}
				if (that.hasInfoDel && !that.infoWindowDel) {
					if (window.document.getElementById("info-window-del"))
						that.infoWindowDel = window.document.getElementById("info-window-del").addEventListener('click',
							function(e) {
								let info = cloneDeep(that.curInfo)
								that.mapObject.infoWindow.close()
								that.$emit('info-del', info.id) // 通知父组件删除信息
							})
				}
				if (that.hasChoose && (that.mapToolActiveType === 'qq-map-tool-locate' ||
						that.mapToolActiveType === 'qq-map-tool-polygon' ||
						that.mapToolActiveType === 'qq-map-tool-circle' ||
						that.mapToolActiveType === 'qq-map-tool-delete')) {
					if (window.document.getElementById("info-window-addChoose"))
						that.infoWindowAddChoose = window.document.getElementById("info-window-addChoose")
						.addEventListener('click',
							function(e) {
								let info = cloneDeep(that.curInfo)
								that.addChoosedBuildingAreasDistinct([info]) // 已选中项目列表
								that.refreshMarkers() // 刷新点标记和文本，显示选中样式
							})
				}
			},
			// 监听信息窗体关闭
			listenToInfoWindowClose() {
				const that = this
				that.mapObject.infoWindow.on('closeclick', function(ev) {
					that.curInfo = {}
				})
			},
			// 隐藏编辑器半径浮框
			hideMapToolEditorCircleDisDialog() {
				const that = this
				that.mapToolCircleRadiusDis = 0
				that.mapToolCircleRadiusDisShow = false
			},

			// 增加多边形选框或半径选框后，处理选中项目
			afterAddPolygonOrCircleEditor(param) {
				const that = this
				const loading = common.showLoading()
				const inBuildings = that.getInscopeBuildingAreas(param)
				//console.log('inBuildings', inBuildings);
				that.addChoosedBuildingAreasDistinct(inBuildings) // 已选中项目列表
				that.refreshMarkers(loading) // 刷新点标记和文本，显示选中样式
				that.mapToolIdAndBuildings[param.id] = cloneDeep(inBuildings) // 框选id与对应项目
			},
			// 删除多边形选框或半径选框后，处理选中项目
			afterDelPolygonOrCircleEditor(id, type) {
				const that = this
				const buildings = that.mapToolIdAndBuildings[id]
				if (buildings && isArray(buildings) &&
					that.choosedBuildingAreas && isArray(that.choosedBuildingAreas)) {
					let shouldDelete = {}
					buildings.forEach(item => shouldDelete['' + item.id] = item)
					let remainChoosed = []
					that.choosedBuildingAreas.forEach(item => {
						if (!shouldDelete['' + item.id]) remainChoosed.push(cloneDeep(item))
					})
					that.choosedBuildingAreas = remainChoosed
					that.refreshMarkers() // 刷新点标记和文本，显示选中样式

					delete that.mapToolIdAndBuildings[id]

					if (type === 'circle' && that.mapToolIds.circle && isArray(that.mapToolIds.circle)) {
						let index = -1,
							arr = cloneDeep(that.mapToolIds.circle);
						for (let i = 0; i < arr.length; i++) {
							const item = arr[i];
							if ('' + item === '' + id) {
								index = i;
								break;
							}
						};
						if (index != -1) {
							that.mapToolIds.circle.splice(index, 1);
						}
					}
					if (type === 'polygon' && that.mapToolIds.polygon && isArray(that.mapToolIds.polygon)) {
						let index = -1,
							arr = cloneDeep(that.mapToolIds.polygon);
						for (let i = 0; i < arr.length; i++) {
							const item = arr[i];
							if ('' + item === '' + id) {
								index = i;
								break;
							}
						};
						if (index != -1) {
							that.mapToolIds.polygon.splice(index, 1);
						}
					}
				}
			},
			// 初始化编辑器
			initMapEditor() {
				const that = this
				// 初始化几何图形及编辑器
				that.mapObject.editor = new TMap.tools.GeometryEditor({
					map: that.mapObject.map, // 编辑器绑定的地图对象
					overlayList: [ // 可编辑图层
						{
							overlay: new TMap.MultiMarker({
								id: 'toolMarker',
								map: that.mapObject.map,
								styles: {
									"marker": new TMap.MarkerStyle({
										"width": 18,
										"height": 24,
										"src": mapMarker
									})
								}
							}),
							id: 'qq-map-tool-marker'
						},
						{
							overlay: new TMap.MultiPolygon({
								id: 'toolPolygon',
								map: that.mapObject.map,
								styles: {
									highlight: new TMap.PolygonStyle({
										color: 'rgba(255, 255, 0, 0.6)',
									})
								}
							}),
							id: 'qq-map-tool-polygon',
							selectedStyleId: 'highlight'
						},
						{
							overlay: new TMap.MultiCircle({
								id: 'toolCircle',
								map: that.mapObject.map,
								styles: {
									highlight: new TMap.CircleStyle({
										color: 'rgba(255, 255, 0, 0.6)',
									})
								}
							}),
							id: 'qq-map-tool-circle',
							selectedStyleId: 'highlight'
						}
					],
					actionMode: TMap.tools.constants.EDITOR_ACTION.DRAW, // 编辑器的工作模式
					activeOverlayId: 'marker', // 激活图层
					snappable: true, // 开启吸附
					selectable: true
				});
				// 监听绘制中事件
				that.mapObject.editor.on('drawing', (e) => {
					const that = this
					if (that.mapToolActiveType === 'qq-map-tool-circle' && e.geometry && e.geometry.radius) {
						that.mapToolCircleRadiusDis = parseInt(e.geometry.radius || 0)
						if (!that.mapToolCircleRadiusDisShow) that.mapToolCircleRadiusDisShow = true
					} else {
						that.hideMapToolEditorCircleDisDialog()
					}
				})
				// 监听绘制结束事件，获取绘制几何图形
				that.mapObject.editor.on('draw_complete', (geometry) => {
					const loading = common.showLoading()
					if (geometry.position) {
						// 点标记
						that.mapToolIds.marker.push(geometry.id)
						that.clearMapEditor('polygon')
						that.clearMapEditor('circle')
						that.toAddMarker(geometry.id, geometry.position.lat, geometry.position.lng)
					} else if (geometry.paths) {
						// 多边形
						that.mapToolIds.polygon.push(geometry.id)
						that.clearMapEditor('marker')
						// 获取经纬度范围内的项目
						const param = {
							id: geometry.id,
							type: 'polygon',
							paths: geometry.paths
						}
						that.afterAddPolygonOrCircleEditor(param);
					} else if (geometry.radius) {
						// 半径
						that.hideMapToolEditorCircleDisDialog()
						that.mapToolIds.circle.push(geometry.id)
						that.clearMapEditor('marker')
						// 获取经纬度范围内的项目
						const param = {
							id: geometry.id,
							type: 'circle',
							center: geometry.center,
							radius: geometry.radius
						}
						that.afterAddPolygonOrCircleEditor(param);
					}
					if (loading) loading.close()
				});
				// 监听框选删除事件
				that.mapObject.editor.on('delete_complete', function(e) {
					const loading = common.showLoading()
					e.forEach(item => {
						let type = '';
						if (item.paths) {
							type = 'polygon';
							let areaId = item.id.substring(5);
							that.delAreaSelected(areaId);
						}
						if (item.radius) {
							type = 'circle';
							let tradeId = item.id.substring(6);
							that.delTradeAreaSelected(tradeId);
						}
						that.afterDelPolygonOrCircleEditor(item.id, type);
					})
					if (loading) loading.close()
				})
			},
			// 获取图层
			getEditorOverlay(id) {
				const that = this;
				const overlayList = that.mapObject.editor.getOverlayList();
				if (overlayList && isArray(overlayList)) {
					for (let overlay of overlayList) {
						if (overlay.id === id) {
							return overlay.overlay;
						}
					}
				}
			},
			// 根据经纬度，逆编码地址，弹出新增
			toAddMarker(id, lat, lng) {
				const that = this
				const loading = common.showLoading({
					text: '获取地址中'
				})
				geocoder({
						lat,
						lng
					})
					.then(res => {
						loading.close()
						const {
							data: {
								result: {
									ad_info: {
										province,
										city,
										district,
										adcode
									},
									address,
									formatted_addresses: {
										recommend
									}
								}
							},
						} = res
						that.$emit('info-add', {
							id,
							lat,
							lng,
							name: recommend,
							province,
							city,
							area: district,
							adcode,
							address
						}) // 通知父组件编辑信息
					})
					.catch(() => {
						loading.close()
						that.clearMapEditor('marker')
					})
			},
			// 1、去重“已选中项目”；2、当前开启的点位类型对该项目的总数为0则不添加
			addChoosedBuildingAreasDistinct(inBuildings) {
				const that = this
				let bMap = {}

				const pointTypeKeys = Object.keys(that.point_types_show)
				//console.log('pointTypeKeys', pointTypeKeys);
				if ((inBuildings || []).length>0 && (pointTypeKeys || []).length>0) {
					inBuildings.forEach(item => {
						let sum = 0
						pointTypeKeys.forEach(pointId => {
							if (!!that.point_types_show[pointId] && !!item.point_num_sum[pointId]) {
								let nums = item.point_num_sum[pointId]
								if (that.showInstalledNum) { //仅显示已安装数（目前只有巡检项目相关）
									sum += nums.installed_num || 0
								} else if (that.showUninstalledNum) { //仅显示未安装数（目前只有新安装项目相关）
									sum += nums.uninstalled_num || 0
								} else { // 用于锁定、合同
									sum += accAdd(nums.available_num || 0, nums.movable_num || 0)
								}
							}
						})
						item._temp_sum = sum
					})

					that.choosedBuildingAreas.forEach(item => {
						bMap['' + item.id] = cloneDeep(item)
					})
					inBuildings.forEach(item => {
						if (item._temp_sum > 0) {
							let _item = cloneDeep(item);
							const old_dis_obj = (bMap['' + item.id] || {}).dis_obj || null;
							if(!!old_dis_obj && !!item.dis_obj){
								if(item.dis_obj.dis > old_dis_obj.dis){
									_item.dis_obj = old_dis_obj;
								}
							}
							bMap['' + item.id] = _item;
						}
					})
					//console.log('inBuildings2', inBuildings);
					that.choosedBuildingAreas = Object.values(bMap).map(item => (item))
					//console.log('choosedBuildingAreas', that.choosedBuildingAreas);
				}
			},
			// 获取框选范围内项目
			getInscopeBuildingAreas(_param = {}) {
				const that = this
				let param = Object.assign({
					type: ''
				}, _param)
				let inArray = []
				if (param.type === 'circle') {
					Object.values(that.buildingAreas).forEach((item) => {
						const path = [new TMap.LatLng(item.lat, item.lng), new TMap.LatLng(param.center.lat, param.center.lng)]
						const cur_dis = parseFloat(TMap.geometry.computeDistance(path) || 0);
						const cur_title = param.title || '';
						if(!item.dis_obj){ 
							item.dis_obj = {
								dis: cur_dis,
								title: cur_title
							};
						} else { 
							if(cur_dis <= item.dis_obj.dis){
								item.dis_obj = {
									dis: cur_dis,
									title: cur_title
								};
							}
						}
					})
					inArray = Object.values(that.buildingAreas).filter((item) => {
						return (item.dis_obj||{}).dis <= param.radius;
					});
				}
				if (param.type === 'polygon') {
					inArray = Object.values(that.buildingAreas).filter((item) => {
						return TMap.geometry.isPointInPolygon(new TMap.LatLng(item.lat, item.lng), param.paths)
					})
				}
				return inArray;
			},
			// 移除已选择项目
			removeChoosed(e) {
				const that = this
				let idx = -1
				if (that.choosedBuildingAreas && isArray(that.choosedBuildingAreas)) {
					that.choosedBuildingAreas.forEach((item, index) => {
						if (item.id == e) {
							idx = index - 0
						}
					})
				}
				if (idx != -1) {
					that.choosedBuildingAreas.splice(idx, 1)
					that.refreshMarkers()
				}
			},
			// 清除一个标记
			clearOneMarker(id) {
				const that = this;
				const cur1 = that.mapObject.marker.getGeometryById('marker' + id);
				if(!!cur1) {
					that.mapObject.marker.remove(['marker' + id])
					that.mapObject.label.remove(['label' + id])
				} else {
					that.getEditorOverlay('qq-map-tool-marker').remove([id])
				}
			},
			// 清除地图盘编辑器编辑数据
			clearMapEditor(type) {
				const that = this
				const idType = 'qq-map-tool-' + type
				const ids = cloneDeep(that.mapToolIds[type])
				const overlay = that.getEditorOverlay(idType)
				//console.log('marker', that.mapToolIds[type])
				if (isArray(ids) && ids.length > 0) {
					overlay.remove(ids)
					that.mapToolIds[type] = []
					ids.forEach(id => {
						delete that.mapToolIdAndBuildings[id]
					})
					if (type === 'polygon') that.area_selected = []
					if (type === 'circle') that.trade_area_selected = []
				}
			},
			// 清除全部编辑数据
			clearEditor() {
				const that = this
				const loading = common.showLoading()
				that.clearMapEditor('marker')
				that.clearMapEditor('polygon')
				that.clearMapEditor('circle')
				that.choosedBuildingAreas = []
				loading.close()
			},
			// 退出编辑模式
			exitEditor(flag = true) {
				const that = this
				that.clearEditor()
				that.mapToolActiveType = ''
				that.mapObject.editor.setActiveOverlay('');
				if (flag) that.hideChoosedBox = true
				that.refreshMarkers()
			},
			// 点击地图编辑器，切换当前活跃的编辑器
			async clickQQMapTool(e) {
				const that = this
				const curId = e.target.dataset.id
				let activeMarker = false
				if (that.mapObject.infoWindow) that.mapObject.infoWindow.close()
				if (curId === 'qq-map-tool-marker') { // 新增项目时
					activeMarker = that.mapToolActiveType !== 'qq-map-tool-marker'
					that.exitEditor()
					if (activeMarker) {
						that.mapToolActiveType = curId
					}
				} else if (curId === 'qq-map-tool-reset') { // 清除选点时
					that.hideChoosedBox = false
					that.clearEditor()
					that.refreshMarkers()
				} else {
					that.hideChoosedBox = false
					// 点选、多边形、半径、删除选框时
					let curFlag = that.mapToolActiveType === 'qq-map-tool-locate' ||
						that.mapToolActiveType === 'qq-map-tool-polygon' ||
						that.mapToolActiveType === 'qq-map-tool-circle' ||
						that.mapToolActiveType === 'qq-map-tool-delete'; //原来的

					let chooseFlag = curId === 'qq-map-tool-locate' ||
						curId === 'qq-map-tool-polygon' ||
						curId === 'qq-map-tool-circle' ||
						curId === 'qq-map-tool-delete'; // 点击的

					let notClearFlag = curFlag && chooseFlag;
					if (!notClearFlag) that.clearEditor() // 清除数据和选框
					that.mapToolActiveType = curId
				}
				if (curId === 'qq-map-tool-delete') {
					that.mapObject.editor.setActiveOverlay(
						'qq-map-tool-polygon'); // 删除需要激活的图层是INTERACT类型的，所以此处暂时多边形的图层
					that.mapObject.editor.setActionMode(TMap.tools.constants.EDITOR_ACTION.INTERACT)
				} else if (curId === 'qq-map-tool-locate') {
					that.mapObject.editor.setActiveOverlay('');
				} else if (curId !== 'qq-map-tool-reset' && curId !== 'qq-map-tool-marker' || (curId ===
						'qq-map-tool-marker' && activeMarker)) {
					that.mapObject.editor.setActionMode(TMap.tools.constants.EDITOR_ACTION.DRAW)
					that.mapObject.editor.setActiveOverlay(curId);
				}
			},
			// 关闭弹窗
			dialogCUClose(formName) {
				const that = this
				switch (formName) {
					case 'radiusForm':
						that.$refs['radiusForm'].clearValidate()
						that.resetRadiusForm()
						break
				}
			},
			// 查询地址
			async searchAddress() {
				const that = this

				if (!that.searchForm.pca || that.searchForm.pca.length == 0) {
					common.message({
						message: '请选择省市',
						type: 'error'
					})
					return false
				}
				if (!that.searchForm.address) {
					common.message({
						message: '请输入地址',
						type: 'error'
					})
					return false
				}
				const loading = common.showLoading({
					text: '搜索中'
				})
				let search_data = {
					keyword: that.searchForm.address,
					boundary: that.searchForm.pca[that.searchForm.pca.length - 1]
				}
				/* if(that.hasInfoAdd){
					search_data.category = '房产小区'
				} */
				search_address(search_data)
					.then(res => {
						const {
							code,
							data: {
								data
							}
						} = res
						if (code == 200) {
							loading.close()
							that.searchAddresses = data
							that.searchDialogVisible = true
						}
					})
					.catch(() => {
						loading.close()
					})
			},
			// 关闭查询结果弹框
			closeSearchDialog() {
				const that = this
				that.searchDialogVisible = false
				that.searchAddresses = []
			},
			// 确认半径辐射
			async confirmSearchADItemToAddCircle() {
				const that = this

				let lat = cloneDeep(that.radiusLatLng.lat)
				let lng = cloneDeep(that.radiusLatLng.lng)
				let radius = cloneDeep(that.radiusForm.radius)

				// 关闭“辐射半径dialog”
				that.dialogRadius = false
				that.dialogRadiusLoading = false

				const loading = common.showLoading({
					text: '框定中'
				})

				// 增加辐射选框
				await that.addCircle(lat, lng, radius)

				// 重置圆心经纬度
				that.radiusLatLng = {
					lat: null,
					lng: null
				}

				loading.close();
			},
			// 新增多边形框选
			addPolygon(paths = [], geometryId = generateUUID()) {
				const that = this
				return new Promise(resolve => {
					if (!paths || paths.length <= 0) resolve()
					let Overlay = that.getEditorOverlay('qq-map-tool-polygon');

					// 新增多边形框选
					let id = geometryId;
					let p = paths;

					Overlay.add({
						id: id,
						paths: p
					})
					that.mapToolIds.polygon.push(id) // 存入选框ids
					const param = {
						id: id,
						type: 'polygon',
						paths: p
					}
					that.afterAddPolygonOrCircleEditor(param)

					resolve()
				})

			},
			// 新增半径框选
			addCircle(lat, lng, radius = 100, geometryId = generateUUID(), title = '') {
				const that = this
				return new Promise(resolve => {
					let Overlay = that.getEditorOverlay('qq-map-tool-circle');

					// 新增半径框选
					let id = geometryId;
					let c = new TMap.LatLng(lat, lng);
					let r = parseInt(radius);

					Overlay.add({
						id: id,
						center: c,
						radius: r
					})
					that.mapToolIds.circle.push(id) // 存入选框ids
					const param = {
						id: id,
						type: 'circle',
						center: c,
						radius: r,
						title: title
					}
					that.afterAddPolygonOrCircleEditor(param)

					resolve()
				})

			},
			// 选择查询结果，定位到地图中心
			chooseSearchADItemToMapCenter({
				location: {
					lat,
					lng
				}
			}) {
				const that = this
				that.mapObject.map.easeTo({
					center: new TMap.LatLng(lat, lng),
					zoom: 15
				}, {
					duration: 1000
				});
				that.closeSearchDialog()
			},
			// 选择查询结果，弹出新增项目框，自动填充
			chooseSearchADItemToAddPoint({
				ad_info: {
					province,
					city,
					district,
					adcode
				},
				address,
				location: {
					lat,
					lng
				},
				title
			}) {
				const that = this
				that.mapObject.map.easeTo({
					center: new TMap.LatLng(lat, lng),
					zoom: that.mapObject.map.getZoom() < that.mapDefaultZoom ? that.mapDefaultZoom : that.mapObject
						.map.getZoom()
				}, {
					duration: 1000
				});
				that.closeSearchDialog()
				that.$emit('info-add', {
					lat,
					lng,
					name: title,
					province,
					city,
					area: district,
					adcode,
					address
				})
			},
			// 查询结果，弹框设置半径，半径框选
			chooseSearchADItemToAddCircle({
				location: {
					lat,
					lng
				}
			}) {
				const that = this
				that.mapObject.map.easeTo({
					center: new TMap.LatLng(lat, lng),
					zoom: that.mapObject.map.getZoom() < that.mapDefaultZoom ? that.mapDefaultZoom : that.mapObject
						.map.getZoom()
				}, {
					duration: 1000
				});
				that.radiusLatLng = {
					lat,
					lng
				}
				that.showRadiusDialog()
				that.closeSearchDialog()
			},
			// 显示半径输入弹框
			showRadiusDialog() {
				const that = this
				that.dialogRadius = true
				that.dialogRadiusLoading = false
				that.resetRadiusForm()
				that.$refs['radiusForm'] && this.$refs['radiusForm'].resetFields()
			},
			// 清空辐射半径form数据
			resetRadiusForm() {
				this.radiusForm = {
					radius: null
				}
			},
			// 获取选中项目的信息
			generateChooseds(isOne = false) {
				const that = this
				let buildings = []
				if (isTrue(isOne)) {
					buildings = [cloneDeep(that.curInfo)]
					that.mapObject.infoWindow.close()
				} else {
					buildings = cloneDeep(that.choosedBuildingAreas)
				}

				if (!that.showInstalledNum) {
					let all_can = {},
						to = {},
						can = {},
						points_num = {},
						all_points_num = {},
						one_limit = {};
					if (buildings && isArray(buildings)) {
						buildings.forEach(item => {
							let points = (item.point_dianti || []).concat(item.point_churukou || [])
							points.forEach(point => {
								const key = item.id + '_' + point.point_type_id
								to[key] = 0
								let _can = 0
								if (that.showUninstalledNum) {
									_can = point.uninstalled_num || 0
								} else {
									_can = accAdd(point.movable_num || 0, point.available_num || 0)
								}
								can[key] = _can - 0
								all_can[point.point_type_id] = accAdd((all_can[point
									.point_type_id] || 0), _can - 0)
								if (that.showUninstalledNum) {
									points_num[key] = point.uninstalled_num - 0
									all_points_num[point.point_type_id] = accAdd(all_points_num[point
										.point_type_id] || 0, point.uninstalled_num - 0)
								} else {
									points_num[key] = point.num - 0
									all_points_num[point.point_type_id] = accAdd(all_points_num[point
										.point_type_id] || 0, point.num - 0)
								}
								if (point.point_type_pid == 119) one_limit[point.point_type_id] = false
							})
							// 大门数
							item.all_door = item.door || 0
							// todo 项目总单元数，需要读取媒体表的楼栋和单元生成具体数量
							// 此处暂时显示为楼栋数*最大单元
							item.all_unit = accMul((item.building_count || 0), (item.unit_count_max || 0))
						})
					}
					return {
						to: to,
						can: can,
						all_can: all_can,
						points_num: points_num,
						all_points_num: all_points_num,
						building_areas: buildings,
						date_range: cloneDeep(that.dateRange),
						one_limit: one_limit
					}
				} else {
					let returnObj = {
						buildings: [],
						point_types: cloneDeep(that.pointTypes),
						point_type: {}
					}
					const ptmKeys = Object.keys(that.point_types_map)
					if (isArray(ptmKeys) && ptmKeys.length > 0) {
						ptmKeys.forEach(key => {
							returnObj.point_type[key] = that.point_types_map[key].name
						})
					}
					let buils = buildings.filter(i => {
						let flag = true
						flag = flag && i.installed_media != undefined
						flag = flag && JSON.stringify(i.installed_media) != "{}"
						flag = flag && that.pointTypes.length > 0
						let ptFlag = false
						that.pointTypes.forEach(pt => {
							ptFlag = ptFlag || i.installed_media[pt]
						})
						flag = flag && ptFlag
						return flag
					}).map(item => {
						return {
							id: item.id,
							name: item.name,
							media: item.installed_media
						}
					})

					if (isArray(buils) && buils.length > 0) {
						buils.forEach(b => {
							let building_item = {
								id: b.id,
								name: b.name
							}
							const keys = Object.keys(b.media)
							if (isArray(keys) && keys.length > 0) {
								keys.forEach(mk => {
									if (that.pointTypes.indexOf(parseInt(mk)) > -1) {
										let m = b.media[mk]
										building_item[b.id + '_' + mk] = {
											num: m.num,
											qrcodes: m.qrcodes,
											idMap: m.idMap
										}
									}

								})
							}
							returnObj.buildings.push(building_item)
						})
					}
					//console.log(returnObj)
					return returnObj
				}
			},
			// 确认配置
			confirmChooseSetting(isOne = false) {
				const that = this
				if(!!that.chooseBuildingOnly){
					that.$emit('confirm-choose', (that.choosedBuildingAreas || []).map(b => {
						return {
							id: parseInt(b.id),
							dis_obj: b.dis_obj || {dis:0, title:''}
						}
					}));
					that.clearEditor();
					that.refreshMarkers();
					that.choosedBuildingAreas = [];
				}else{
					let setting = that.generateChooseds(isOne)
					if (!that.showInstalledNum) {
						// 弹出配置框
						that.$refs.settingDialog.initDistForm(cloneDeep(setting))
						that.showSettingDialog = true
					} else {
						common.savePageData(setting, 'MapChooseBuildingSetting')
						that.$emit('confirm-choose')
					}
				}
			},
			settingDialogOnConfirm(data) {
				const that = this
				//console.log(data)
				common.savePageData(data, 'MapPointDistSetting')
				that.showSettingDialog = false
				that.$emit('confirm-choose')
			}
		}
	}
</script>

<style scoped lang="scss">
	.app-map-container{
		display: relative;
	}
	.qq-map-container {
		/* 50= navbar  50  */
		width: 100%;
		height: calc(100vh - 50px);

		/deep/.info-operate {
			cursor: pointer !important;
			margin: 0 auto;
		}
	}

	.top-tool {
		border-radius: 5px;

		&.top-tool-switch {
			padding: 4px 0;
		}

		&.top-tool-select {}
	}

	.circleRadiusDisBox {
		width: 80px;
		height: 20px;
		padding: 0;
		font-size: 13px;
		background-color: #eaf9ff;
		border: 1px solid #ddd;
		color: #333;
		border-radius: 5px;
		line-height: 20px;
		text-align: center;
		box-shadow: 0 0 1px rgba(0, 0, 0, 0.1);
	}

	.address-search {
		position: absolute;
		top: 60px;
		width: 100%;
		z-index: 2000;
	}

	.hasTagsView {
		.qq-map-container {
			/* 84 = navbar + tags-view = 50 + 34 */
			height: calc(100vh - 85px);
		}

		.address-search {
			top: 95px;
		}

		.choosed-building-area {
			top: 155px;

			.choosed-building-areas-list {
				max-height: calc(100vh - 295px);
			}
		}
	}

	.choosed-building-area {
		position: absolute;
		top: 120px;
		width: 300px;
		border-top-right-radius: 5px;
		border-bottom-right-radius: 5px;
		z-index: 2001;

		.choosed-box {
			position: relative;

			.choosed-export {
				position: absolute;
				top: 0;
				right: 0;
			}
		}

		.choose-operator {
			margin: 0 auto;
		}

		.choosed-building-areas-list {
			max-height: calc(100vh - 260px);
			overflow-y: auto;

			&::-webkit-scrollbar {
				/*滚动条整体样式*/
				width: 4px;
				/*高宽分别对应横竖滚动条的尺寸*/
				height: 4px;
			}

			&::-webkit-scrollbar-thumb {
				/*滚动条里面小方块*/
				border-radius: 5px;
				background: rgba(0, 0, 0, 0.2);
			}

			&::-webkit-scrollbar-track {
				/*滚动条里面轨道*/
				border-radius: 0;
				background: rgba(0, 0, 0, 0.1);
			}

			.choosed-building-areas-list-item:hover {
				background-color: #f5f5f5;
				opacity: 0.8;

				.choosed-building-areas-list-item-name {
					cursor: default;
				}
			}
		}
	}

	.choosed-building-area-enter-active,
	.choosed-building-area-leave-active {
		opacity: 1;
		transition: all .5s ease;
	}

	.choosed-building-area-enter,
	.choosed-building-area-leave-to {
		opacity: 0;
	}

	.address-cascader {
		width: 150px;
		height: 30px !important;

		/deep/.el-input.el-input--small.el-input--suffix {
			height: 30px !important;

			.el-input__inner {
				border: 0 !important;
				height: 30px !important;
			}
		}
	}

	.address-input {
		width: 350px;
		height: 30px !important;
		padding: 0 !important;

		/deep/.el-input-group__prepend {
			padding: 0 !important;
		}
	}

	.qq-map-tool-control {
		position: absolute;
		bottom: 5px;
		left: 0;
		right: 0;
		margin: 0 auto;
		z-index: 1001;

		.qq-map-tool-item {
			background-color: #ffffff;
			border: 1px solid #ffffff;
			border-radius: 3px;
			box-shadow: 0 1px 2px 0 #E4E7EF;
			height: 60px;
			padding: 3px;
			margin: 1px;
			display: flex;
			flex-direction: column;
			flex-wrap: nowrap;
			justify-content: center;
			align-items: center;

			.qq-map-tool-item-icon {
				width: 36px;
				height: 40px !important;
				padding: 0;
				background-size: 32px 32px;
				background-position: 2px 2px;
				background-repeat: no-repeat;
			}

			.qq-map-tool-item-title {
				font-size: 16px;
				padding-top: 2px;
			}
		}

		.qq-map-tool-item:hover {
			border-color: #789CFF;
			cursor: pointer;
		}

		.qq-map-tool-item.active {
			border-color: #D5DFF2;
			background-color: #D5DFF2;
		}
	}
</style>
